[C#] C# 实现的 AES 加密算法 →→→→→进入此内容的聊天室

来自 , 2021-03-26, 写在 C#, 查看 119 次.
URL http://www.code666.cn/view/4c56392b
  1. using System;
  2. using System.IO;
  3. using System.Security.Cryptography;
  4.  
  5. //
  6. // Sample encrypt/decrypt functions
  7. // Parameter checks and error handling
  8. // are ommited for better readability
  9. // @author:Ashwin Kumar
  10. // Date : 12/3/2008
  11. public class AESEncryptionUtility
  12. {
  13.         static int  Main(string[] args)
  14.     {
  15.                 if (args.Length < 2)
  16.             {
  17.                 Console.WriteLine("Usage: AESEncryptionUtility infile outFile");
  18.                 return 1;
  19.             }
  20.                         string infile = args[0];
  21.             string outfile = args[1];
  22.                         //string keyfile = args[2];
  23.                         //var key = File.ReadAllBytes(keyfile);
  24.                         Encrypt(infile,outfile,"test");
  25.                         Decrypt(outfile,"_decrypted"+infile,"test");
  26.                         return 0;
  27.  
  28.         }
  29.  
  30.     // Encrypt a byte array into a byte array using a key and an IV
  31.     public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
  32.     {
  33.         // Create a MemoryStream to accept the encrypted bytes
  34.         MemoryStream ms = new MemoryStream();
  35.         // Create a symmetric algorithm.
  36.         // We are going to use Rijndael because it is strong and
  37.         // available on all platforms.
  38.         // You can use other algorithms, to do so substitute the
  39.         // next line with something like
  40.         //      TripleDES alg = TripleDES.Create();
  41.         Rijndael alg = Rijndael.Create();
  42.         // Now set the key and the IV.
  43.         // We need the IV (Initialization Vector) because
  44.         // the algorithm is operating in its default
  45.         // mode called CBC (Cipher Block Chaining).
  46.         // The IV is XORed with the first block (8 byte)
  47.         // of the data before it is encrypted, and then each
  48.         // encrypted block is XORed with the
  49.         // following block of plaintext.
  50.         // This is done to make encryption more secure.
  51.         // There is also a mode called ECB which does not need an IV,
  52.         // but it is much less secure.
  53.         alg.Key = Key;
  54.         alg.IV = IV;
  55.         // Create a CryptoStream through which we are going to be
  56.         // pumping our data.
  57.         // CryptoStreamMode.Write means that we are going to be
  58.         // writing data to the stream and the output will be written
  59.         // in the MemoryStream we have provided.
  60.         CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
  61.         // Write the data and make it do the encryption
  62.         cs.Write(clearData, 0, clearData.Length);
  63.         // Close the crypto stream (or do FlushFinalBlock).
  64.         // This will tell it that we have done our encryption and
  65.         // there is no more data coming in,
  66.         // and it is now a good time to apply the padding and
  67.         // finalize the encryption process.
  68.         cs.Close();
  69.         // Now get the encrypted data from the MemoryStream.
  70.         // Some people make a mistake of using GetBuffer() here,
  71.         // which is not the right way.
  72.         byte[] encryptedData = ms.ToArray();
  73.         return encryptedData;
  74.     }
  75.  
  76.     // Encrypt a string into a string using a password
  77.     //    Uses Encrypt(byte[], byte[], byte[])
  78.     public static string Encrypt(string clearText, string Password)
  79.     {
  80.         // First we need to turn the input string into a byte array.
  81.         byte[] clearBytes =
  82.           System.Text.Encoding.Unicode.GetBytes(clearText);
  83.         // Then, we need to turn the password into Key and IV
  84.         // We are using salt to make it harder to guess our key
  85.         // using a dictionary attack -
  86.         // trying to guess a password by enumerating all possible words.
  87.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  88.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
  89.             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  90.         // Now get the key/IV and do the encryption using the
  91.         // function that accepts byte arrays.
  92.         // Using PasswordDeriveBytes object we are first getting
  93.         // 32 bytes for the Key
  94.         // (the default Rijndael key length is 256bit = 32bytes)
  95.         // and then 16 bytes for the IV.
  96.         // IV should always be the block size, which is by default
  97.         // 16 bytes (128 bit) for Rijndael.
  98.         // If you are using DES/TripleDES/RC2 the block size is
  99.         // 8 bytes and so should be the IV size.
  100.         // You can also read KeySize/BlockSize properties off
  101.         // the algorithm to find out the sizes.
  102.         byte[] encryptedData = Encrypt(clearBytes,
  103.                  pdb.GetBytes(32), pdb.GetBytes(16));
  104.  
  105.         // Now we need to turn the resulting byte array into a string.
  106.         // A common mistake would be to use an Encoding class for that.
  107.         //It does not work because not all byte values can be
  108.         // represented by characters.
  109.         // We are going to be using Base64 encoding that is designed
  110.         //exactly for what we are trying to do.
  111.         return Convert.ToBase64String(encryptedData);
  112.     }
  113.  
  114.     // Encrypt bytes into bytes using a password
  115.     //    Uses Encrypt(byte[], byte[], byte[])
  116.     public static byte[] Encrypt(byte[] clearData, string Password)
  117.     {
  118.         // We need to turn the password into Key and IV.
  119.         // We are using salt to make it harder to guess our key
  120.         // using a dictionary attack -
  121.         // trying to guess a password by enumerating all possible words.
  122.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  123.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
  124.             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  125.  
  126.         // Now get the key/IV and do the encryption using the function
  127.         // that accepts byte arrays.
  128.         // Using PasswordDeriveBytes object we are first getting
  129.         // 32 bytes for the Key
  130.         // (the default Rijndael key length is 256bit = 32bytes)
  131.         // and then 16 bytes for the IV.
  132.         // IV should always be the block size, which is by default
  133.         // 16 bytes (128 bit) for Rijndael.
  134.         // If you are using DES/TripleDES/RC2 the block size is 8
  135.         // bytes and so should be the IV size.
  136.         // You can also read KeySize/BlockSize properties off the
  137.         // algorithm to find out the sizes.
  138.         return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));
  139.     }
  140.  
  141.     // Encrypt a file into another file using a password
  142.     public static void Encrypt(string fileIn,
  143.                 string fileOut, string Password)
  144.     {
  145.         // First we are going to open the file streams
  146.         FileStream fsIn = new FileStream(fileIn,
  147.             FileMode.Open, FileAccess.Read);
  148.         FileStream fsOut = new FileStream(fileOut,
  149.             FileMode.OpenOrCreate, FileAccess.Write);
  150.         // Then we are going to derive a Key and an IV from the
  151.         // Password and create an algorithm
  152.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  153.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
  154.             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  155.         Rijndael alg = Rijndael.Create();
  156.         alg.Key = pdb.GetBytes(32);
  157.         alg.IV = pdb.GetBytes(16);
  158.         // Now create a crypto stream through which we are going
  159.         // to be pumping data.
  160.         // Our fileOut is going to be receiving the encrypted bytes.
  161.         CryptoStream cs = new CryptoStream(fsOut,
  162.             alg.CreateEncryptor(), CryptoStreamMode.Write);
  163.  
  164.         // Now will will initialize a buffer and will be processing
  165.         // the input file in chunks.
  166.         // This is done to avoid reading the whole file (which can
  167.         // be huge) into memory.
  168.         int bufferLen = 4096;
  169.         byte[] buffer = new byte[bufferLen];
  170.         int bytesRead;
  171.         do {
  172.             // read a chunk of data from the input file
  173.             bytesRead = fsIn.Read(buffer, 0, bufferLen);
  174.             // encrypt it
  175.             cs.Write(buffer, 0, bytesRead);
  176.         } while(bytesRead != 0);
  177.         // close everything
  178.         // this will also close the unrelying fsOut stream
  179.         cs.Close();
  180.         fsIn.Close();
  181.     }
  182.  
  183.     // Decrypt a byte array into a byte array using a key and an IV
  184.     public static byte[] Decrypt(byte[] cipherData,
  185.                                 byte[] Key, byte[] IV)
  186.     {
  187.         // Create a MemoryStream that is going to accept the
  188.         // decrypted bytes
  189.         MemoryStream ms = new MemoryStream();
  190.         // Create a symmetric algorithm.
  191.         // We are going to use Rijndael because it is strong and
  192.         // available on all platforms.
  193.         // You can use other algorithms, to do so substitute the next
  194.         // line with something like
  195.         //     TripleDES alg = TripleDES.Create();
  196.         Rijndael alg = Rijndael.Create();
  197.         // Now set the key and the IV.
  198.         // We need the IV (Initialization Vector) because the algorithm
  199.         // is operating in its default
  200.         // mode called CBC (Cipher Block Chaining). The IV is XORed with
  201.         // the first block (8 byte)
  202.         // of the data after it is decrypted, and then each decrypted
  203.         // block is XORed with the previous
  204.         // cipher block. This is done to make encryption more secure.
  205.         // There is also a mode called ECB which does not need an IV,
  206.         // but it is much less secure.
  207.         alg.Key = Key;
  208.         alg.IV = IV;
  209.         // Create a CryptoStream through which we are going to be
  210.         // pumping our data.
  211.         // CryptoStreamMode.Write means that we are going to be
  212.         // writing data to the stream
  213.         // and the output will be written in the MemoryStream
  214.         // we have provided.
  215.         CryptoStream cs = new CryptoStream(ms,
  216.             alg.CreateDecryptor(), CryptoStreamMode.Write);
  217.         // Write the data and make it do the decryption
  218.         cs.Write(cipherData, 0, cipherData.Length);
  219.         // Close the crypto stream (or do FlushFinalBlock).
  220.         // This will tell it that we have done our decryption
  221.         // and there is no more data coming in,
  222.         // and it is now a good time to remove the padding
  223.         // and finalize the decryption process.
  224.         cs.Close();
  225.         // Now get the decrypted data from the MemoryStream.
  226.         // Some people make a mistake of using GetBuffer() here,
  227.         // which is not the right way.
  228.         byte[] decryptedData = ms.ToArray();
  229.         return decryptedData;
  230.     }
  231.  
  232.     // Decrypt a string into a string using a password
  233.     //    Uses Decrypt(byte[], byte[], byte[])
  234.     public static string Decrypt(string cipherText, string Password)
  235.     {
  236.         // First we need to turn the input string into a byte array.
  237.         // We presume that Base64 encoding was used
  238.         byte[] cipherBytes = Convert.FromBase64String(cipherText);
  239.         // Then, we need to turn the password into Key and IV
  240.         // We are using salt to make it harder to guess our key
  241.         // using a dictionary attack -
  242.         // trying to guess a password by enumerating all possible words.
  243.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  244.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
  245.             0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  246.         // Now get the key/IV and do the decryption using
  247.         // the function that accepts byte arrays.
  248.         // Using PasswordDeriveBytes object we are first
  249.         // getting 32 bytes for the Key
  250.         // (the default Rijndael key length is 256bit = 32bytes)
  251.         // and then 16 bytes for the IV.
  252.         // IV should always be the block size, which is by
  253.         // default 16 bytes (128 bit) for Rijndael.
  254.         // If you are using DES/TripleDES/RC2 the block size is
  255.         // 8 bytes and so should be the IV size.
  256.         // You can also read KeySize/BlockSize properties off
  257.         // the algorithm to find out the sizes.
  258.         byte[] decryptedData = Decrypt(cipherBytes,
  259.            pdb.GetBytes(32), pdb.GetBytes(16));
  260.         // Now we need to turn the resulting byte array into a string.
  261.         // A common mistake would be to use an Encoding class for that.
  262.         // It does not work
  263.         // because not all byte values can be represented by characters.
  264.         // We are going to be using Base64 encoding that is
  265.         // designed exactly for what we are trying to do.
  266.         return System.Text.Encoding.Unicode.GetString(decryptedData);
  267.     }
  268.  
  269.     // Decrypt bytes into bytes using a password
  270.     //    Uses Decrypt(byte[], byte[], byte[])
  271.     public static byte[] Decrypt(byte[] cipherData, string Password)
  272.     {
  273.         // We need to turn the password into Key and IV.
  274.         // We are using salt to make it harder to guess our key
  275.         // using a dictionary attack -
  276.         // trying to guess a password by enumerating all possible words.
  277.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  278.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
  279.             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  280.         // Now get the key/IV and do the Decryption using the
  281.         //function that accepts byte arrays.
  282.         // Using PasswordDeriveBytes object we are first getting
  283.         // 32 bytes for the Key
  284.         // (the default Rijndael key length is 256bit = 32bytes)
  285.         // and then 16 bytes for the IV.
  286.         // IV should always be the block size, which is by default
  287.         // 16 bytes (128 bit) for Rijndael.
  288.         // If you are using DES/TripleDES/RC2 the block size is
  289.         // 8 bytes and so should be the IV size.
  290.         // You can also read KeySize/BlockSize properties off the
  291.         // algorithm to find out the sizes.
  292.         return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));
  293.     }
  294.  
  295.     // Decrypt a file into another file using a password
  296.     public static void Decrypt(string fileIn,
  297.                 string fileOut, string Password)
  298.     {
  299.         // First we are going to open the file streams
  300.         FileStream fsIn = new FileStream(fileIn,
  301.                     FileMode.Open, FileAccess.Read);
  302.         FileStream fsOut = new FileStream(fileOut,
  303.                     FileMode.OpenOrCreate, FileAccess.Write);
  304.         // Then we are going to derive a Key and an IV from
  305.         // the Password and create an algorithm
  306.         PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
  307.             new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
  308.             0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
  309.         Rijndael alg = Rijndael.Create();
  310.         alg.Key = pdb.GetBytes(32);
  311.         alg.IV = pdb.GetBytes(16);
  312.         // Now create a crypto stream through which we are going
  313.         // to be pumping data.
  314.         // Our fileOut is going to be receiving the Decrypted bytes.
  315.         CryptoStream cs = new CryptoStream(fsOut,
  316.             alg.CreateDecryptor(), CryptoStreamMode.Write);
  317.         // Now will will initialize a buffer and will be
  318.         // processing the input file in chunks.
  319.         // This is done to avoid reading the whole file (which can be
  320.         // huge) into memory.
  321.         int bufferLen = 4096;
  322.         byte[] buffer = new byte[bufferLen];
  323.         int bytesRead;
  324.         do {
  325.             // read a chunk of data from the input file
  326.             bytesRead = fsIn.Read(buffer, 0, bufferLen);
  327.             // Decrypt it
  328.             cs.Write(buffer, 0, bytesRead);
  329.         } while(bytesRead != 0);
  330.         // close everything
  331.         cs.Close(); // this will also close the unrelying fsOut stream
  332.         fsIn.Close();
  333.     }
  334.  }
  335. //csharp/1133

回复 "C# 实现的 AES 加密算法"

这儿你可以回复上面这条便签

captcha