2017-04-25 361 views
0

我遇到了Rfc2898DeriveBytes与AES混淆的使用。下面是我发现的代码....使用Rfc2898DeriveBytes进行AES 256位加密

public static string Decrypt(string encryptionKey, string cipherValue) 
    { 
     byte[] cipherBytes = Convert.FromBase64String(cipherValue); 
     using (var encryptor = Aes.Create()) 
     { 
      var pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { (13 element byte array) }); 
      if (encryptor != null) 
      { 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (var ms = new MemoryStream()) 
       { 
        using (var cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(cipherBytes, 0, cipherBytes.Length); 
         cs.Close(); 
        } 
        cipherValue = Encoding.Unicode.GetString(ms.ToArray()); 
       } 
      } 
     } 
     return cipherValue; 
    } 

所以,“的CipherValue”被加密的字符串,同样也适合“的encryptionKey”。如何使用AES和Rfc2898Derive字节的其他示例似乎不适合此代码。我见过的其他例子有一些非常纯文本代替上面的“encryptionKey”参数,但这些例子通常是演示加密而不是解密。

此代码正用于解密我的应用程序的配置文件中的密码。加密已经完成,我没有资源可以告诉我它是如何完成的。我假设密码是使用指定的“encryptionKey”和salt值加密的,以及默认的1000次迭代和最大大小的Key和IV。

我很好奇主要是关于“encryptionKey”参数如何计算的东西。 “cipherValue”是什么被解密,并给我正确的输出。在这里工作的方法是什么,以及我看过的其他例子有什么优点?

加密和安全性并不是我的强项西装......让我知道是否遗漏了任何重要的东西,这可能会为我们提供更多的信息。提前致谢!

+0

盐必须随机选择(第二个参数为Rfc2898DeriveBytes)。不要使用静态盐,因为这会使密码具有确定性,因此不会在语义上安全。观察密文的攻击者可以确定何时之前发送了相同的消息前缀。盐不是秘密的,所以你可以把它和密文一起发送。通常,它只是在密文前面加上,然后在解密之前切掉。 –

回答

1

RFC2898DeriveBytes是一个很差的命名落实PBKDF2,在RFC 2898.定义(为什么它的命名不佳部分是RFC 2898也描述了PBKDF1算法,这是PasswordDeriveBytes使用)

你可以阅读链接的RFC部分中的完整算法,但它的作用是将密码用作密钥,然后取出盐的HMAC和一些状态数据,然后取出HMAC,然后取出HMAC,最大为iterations

其目的是获取输入密码(低熵)并以可预测的方式将其转换为密码密钥(具有高熵),从而难以弄清楚原始密码是什么。

只要所有输入相同,它就会产生相同的答案。但只是稍微改变任何输入就会产生截然不同的答案。

如果你看到的其他方法通过使用Encoding.UTF8.GetBytes()(或类似的)将密码变为密钥,那么是的:这是一个更好的方法(它更难以破解,并且它不会不管你的密码多长时间)。