为什么.Net Framework的加密如此复杂?

时间:2019-05-14 08:26:00

标签: c# .net cryptography aes

在大多数情况下,我需要使用密码对字符串进行加密,然后将其发送/保存到某个地方。以后我想用密码解密它。我没有加密核导弹代码或医疗患者数据!理想的是2个功能:

string Encrypt(string plainText, string password);
string Decrypt(string cipherText, string password);

我看了crypto documentation ...哦,天哪!因此,我尝试自己编写上述调用(see a proof of concept using AES Managed and Base64 encoded payload)。我不是加密专家,为什么我必须对此进行编码?我可能做错了事...

  1. 要从密码中获取密钥,界面需要添加盐。我可以将密码用作盐吗?我可以将IV用作盐吗?也许不是,但是我不想添加另一个参数。
  2. 我可以使用固定输液吗?相同的明文和密码应导致不同的密文,因此我必须在有效负载中提供用于解密的IV。
  3. 我可以在键上加盐并保持IV不变吗?感觉不对。
  4. 创建一个随机数并从中得出IV和关键盐是有效的方法吗?
  5. 如果.Net支持GCM模式,我还会遇到这个问题吗?

1 个答案:

答案 0 :(得分:3)

.NET加密API公开了一个通用加密库,其中包含面向对象的方法来实现加密算法。当然,要使用这些算法和算法实现,您需要对当前尚缺乏的密码学有很好的了解。

这个通用库是实现现有的各种协议所必需的。通常,单个算法不能满足特定的用例(您可以使用密码对字符串进行加密,并根据情况返回其他字符串)。因此,需要选择或设计确实能够满足该用例的协议。该协议可以例如是定义一种容器格式,例如CMS或PGP,例如可以用来加密电子邮件(用例)。

您正在直接尝试应用密码算法来解决您的用例。那是行不通的。您需要一个预制的协议,最好使用预制的API。


请注意,存在许多不同的用例,许多不同的协议,以及关于如何正确创建和实现这些方法的更多意见。例如,Libsodium / NaCl定义了一种称为SecretBox的小型容器格式,该格式确实从您那里承担了一些工作。

但是,由于功能/算法不存在,因此当然不可能在NaCl上实现TLS。再次,.NET需要像.NET API这样的通用加密库,以供其他人实现其协议。


因此,您要么必须硬着头皮尝试创建自己的协议,要么采用现有协议并进行有根据的猜测,以确保其安全性(希望该协议已被审核/更新了几次)。在没有其他贡献者的情况下远离单人项目(例如许多未经审查的示例代码)。

对于您自己的协议,是的,存在一些错误,例如不将密文与盐一起存储。您需要随机(或至少唯一)的盐来确保安全,因此重用密码肯定是安全的。不要让它自己成为一个人的项目,而要借用协议或对其进行审查。


好的,然后迅速:

  
      
  1. 要从密码中获取密钥,界面需要添加盐。我可以将密码用作盐吗?我可以将IV用作盐吗?也许不是,但是我不想添加另一个参数。
  2.   

不,盐必须是唯一的,最好是无规的;密码/盐的组合应该是唯一的(不应重复,甚至不能及时或在不同的域中重复)。

  
      
  1. 我可以使用固定输液吗?相同的明文和密码应导致不同的密文,因此我必须在有效负载中提供用于解密的IV。
  2.   

否,除非键每次都更改值(请参见上文)。对于CBC,IV应该是不可预测的,除非您每次都使用新密钥。

  
      
  1. 我可以在键上加盐并保持IV不变吗?感觉不对。
  2.   

有可能,只要您不重复加盐即可。

  
      
  1. 创建一个随机数并从中得出IV和关键盐是有效的方法吗?
  2.   

这取决于非常具体的细节。换句话说,如果您不知道自己在做什么,我就不会尝试。

  
      
  1. 如果.Net支持GCM模式,我还会遇到这个问题吗?
  2.   

绝对,从某种意义上说,如果您使用GCM,您的问题会更糟,因为使用具有相同密钥和IV的GCM完全被破坏了。


请记住,GCM只是一种算法,而不是协议,它无法独自解决您的用例。