我正在使用C#中的对称加密/解密例程。我知道之前有关于这个主题的一些问题,但大多数答案似乎是关于加密的哲学,而不是给出实际的代码。
更新:我真的很想看到一些代码,而不仅仅是链接。非常感谢!
答案 0 :(得分:14)
查看this page底部的示例代码。
在此复制粘贴:
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);
答案 1 :(得分:7)
这是我在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());
}
}
答案 2 :(得分:6)
对于初学者来说,键不是字符串,键是二进制blob。 PlainText是相同的,它实际上不是文本,它也是二进制blob。
现在你可以使用Encoding.UTF8.GetBytes(message)
将字符串转换为字节数组,但是当来回转换键时,它通常会使用Convert.ToBase64String
和Convert.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还是其他。链接有足够的样本,所以在这里切割和粘贴是没有意义的。
答案 3 :(得分:2)
你想要的是类库中的cryptoserviceproviders
就像这个AES
答案 4 :(得分:2)
首先使用您选择的编码将文本,键和初始化向量转换为字节。然后使用三重DES提供程序,如下所示:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledes.aspx
如果您认为三重DES过于老派,或者其他什么,那么AES的那个。
出于好奇,您打算如何传达密钥?
答案 5 :(得分:0)
答案 6 :(得分:0)
此方法使用字符串作为加密密码和加密文本。它对于与需要字符串的非 .NET 代码进行互操作很有用。
它使用 OEM 美国编码在二进制数据和字符串之间进行转换,因此唯一的转换是在每个 unicode 字符中添加或删除额外的 0 字节(相对于 UTF8 编码,它动态解释字符的字节)。
>}}}