.NET中的对称加密/解密

Cra*_*rze 12 c# encryption

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

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

ori*_*rip 14

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

在此复制粘贴:

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);
Run Code Online (Sandbox Code Playgroud)

  • @blowdart - 没有.盐和IV需要尽可能独特,但安全地生成它们并不意味着什么.安全随机意味着难以预测的随机性,你不关心你的IV或盐是否被预测 - 无论如何它们都以明文传递/存储. (10认同)
  • Ewww,使用非安全随机创建盐?坏主意. (5认同)

Jan*_*Jan 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());
    }
}
Run Code Online (Sandbox Code Playgroud)


blo*_*art 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)
Run Code Online (Sandbox Code Playgroud)

密钥和IV 必须是加密安全的随机数,不要只键入它们,也不要使用C#的Random函数.密钥和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);
Run Code Online (Sandbox Code Playgroud)

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

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

  • IV 不需要加密安全,只有密钥可以。 (2认同)