.NET中的对称加密/解密

我正在使用C#中的对称加密/解密例程。 我知道之前有关于这个主题的一些问题,但大多数答案似乎是关于加密的哲学,而不是给出实际的代码。

更新:我真的很想看到一些代码,而不仅仅是链接。 非常感谢!

查看本页底部的示例代码。

在此复制粘贴:

int Rfc2898KeygenIterations= 100; int AesKeySizeInBits = 128; String Password = "VerySecret!"; byte[] Salt = new byte[16]; System.Random rnd = new System.Random(); rnd.NextBytes(Salt); byte[] rawPlaintext = System.Text.Encoding.Unicode.GetBytes("This is all clear now!"); byte[] cipherText= null; byte[] plainText= null; using (Aes aes = new AesManaged()) { aes.Padding = PaddingMode.PKCS7; aes.KeySize = AesKeySizeInBits; int KeyStrengthInBytes= aes.KeySize/8; System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 = new System.Security.Cryptography.Rfc2898DeriveBytes(Password, Salt, Rfc2898KeygenIterations); aes.Key = rfc2898.GetBytes(KeyStrengthInBytes); aes.IV = rfc2898.GetBytes(KeyStrengthInBytes); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(rawPlaintext, 0, rawPlaintext.Length); } cipherText= ms.ToArray(); } using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherText, 0, cipherText.Length); } plainText = ms.ToArray(); } } string s = System.Text.Encoding.Unicode.GetString(plainText); Console.WriteLine(s); 

这是我在VB.NET论坛上找到并转换为C#的简单解决方案。 它确实帮助我更好地理解了这个主题。

 // Shamelessly lifted from http://discuss.itacumens.com/index.php?topic=62872.0, // then converted to C# (http://www.developerfusion.com/tools/convert/vb-to-csharp/) and // changed where necessary. public class Encryptor { private static SymmetricAlgorithm _cryptoService = new TripleDESCryptoServiceProvider(); // maybe use AesCryptoServiceProvider instead? // vector and key have to match between encryption and decryption public static string Encrypt(string text, byte[] key, byte[] vector) { return Transform(text, _cryptoService.CreateEncryptor(key, vector)); } // vector and key have to match between encryption and decryption public static string Decrypt(string text, byte[] key, byte[] vector) { return Transform(text, _cryptoService.CreateDecryptor(key, vector)); } private static string Transform(string text, ICryptoTransform cryptoTransform) { MemoryStream stream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(stream, cryptoTransform, CryptoStreamMode.Write); byte[] input = Encoding.Default.GetBytes(text); cryptoStream.Write(input, 0, input.Length); cryptoStream.FlushFinalBlock(); return Encoding.Default.GetString(stream.ToArray()); } } 

好吧,首先,键不是字符串,键是二进制blob。 PlainText是相同的,它实际上不是文本,它也是二进制blob。

当然,您现在可以使用Encoding.UTF8.GetBytes(message)将字符串转换为字节数组,但是当来回转换键时,它会更复杂,您通常使用Convert.ToBase64StringConvert.FromBase64String

不要忘记分组密码还需要一个东西,初始化向量,所以你的方法签名应该是

 byte[] Encrypt(byte[] plainText, byte[] key, byte[] iv) byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv) 

密钥和IV 必须是加密安全的随机数 ,不要只键入它们,也不要使用C#的随机函数。 密钥和IV的大小取决于所使用的密码算法,并且可以通过类上的属性访问。

要生成CSRPNG,您可以执行类似的操作

 RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] key = new byte[algorithm.KeySizeValue / 8]; rng.GetBytes(key); byte[] iv = new byte[algorithm.BlockSizeValue / 8]; rng.GetBytes(iv); 

您还可以使用Rfc2898DeriveBytes类从密码和salt派生密钥和IV,但盐也应该是加密安全的随机数。 您还应该注意,在创建对称算法时,会为您生成安全密钥和IV。

这样,您就可以为文本选择正确的编码,无论是UTF8,ASCII还是其他。 链接有足够的样本,因此在这里切割和粘贴是毫无意义的。

首先使用您选择的编码将文本,键和初始化向量转换为字节。 然后使用三重DES提供程序,如下所示:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledes.aspx

如果您认为三重DES过于老派,或者其他什么,那么也可以使用AES。

出于好奇,您打算如何传达秘密密钥?

GPG用于静止数据。 TLS用于运动中的数据。

GPG http://sourceforge.net/projects/starksoftopenpg/