为什么使用 .Net Framework 进行加密如此复杂?

Why is crypto with .Net Framework so complicated?

在大多数情况下,我需要用密码加密一个字符串,然后 send/save 它在某处。稍后我想用密码解密它。我没有加密核导弹代码或医疗患者数据!理想的是 2 个函数:

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

我看过 crypto documentation... Oh boy! So I try to code the above calls myself (see a proof of concept using AES Managed and Base64 encoded payload)。我不是加密专家,为什么我必须编写代码?我可能做错了什么...

  1. 要从密码中导出密钥,接口需要加盐。我可以使用密码作为盐吗?我可以重复使用 IV 作为盐吗?也许不是,但我不想添加另一个参数。
  2. 我可以使用固定 IV 吗?相同的明文和密码应该会产生不同的密文,所以我必须在有效负载中提供用于解密的 IV。
  3. 我可以对密钥使用盐并保持 IV 不变吗?感觉不对。
  4. 创建随机数并从中导出 IV 和密钥盐是一种有效的方法吗?
  5. 如果 .Net 支持 GCM 模式,我还会遇到这个问题吗?

.NET 加密 API 公开了一个 通用 加密库,其中包含用于实现加密 算法 的面向对象的方法。当然,要使用这些算法和算法实现,你需要对密码学有很好的掌握,而这正是你目前所缺乏的。

需要这个通用库来实现现有的各种协议。通常,单个算法不能满足特定的用例(在您的情况下,使用密码加密字符串,返回不同的字符串)。因此,需要选择或设计一个协议来满足该用例。该协议可以例如定义容器格式,例如 CMS 或 PGP,例如可用于加密电子邮件(用例)。

您正在直接尝试应用加密算法来解决您的用例。那是行不通的。你需要一个 pre-made 协议 ,最好是 pre-made API.


请注意,有许多不同的用例、许多不同的协议以及关于如何正确创建和实施这些协议的更多意见。例如,Libsodium / NaCl 定义了一种名为 SecretBox 的小型容器格式,它确实可以代替您完成一些工作。

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


因此,要么你必须硬着头皮尝试创建你自己的协议,要么你采用现有的协议并进行有根据的猜测它是否安全(希望该协议已经过几次审查/更新) .远离没有额外贡献者的单人项目(比如许多未经审查的示例代码)。

你自己的协议,是的,有没有用密文存储salt之类的错误。你需要一个随机的 - 或者至少是唯一的 - salt 来确保安全,为此重复使用密码肯定 安全。不要让它本身成为一个人的项目,要么借用协议,要么让其审查。


好的,那快点:

  1. To derive the key from the password the interface requires a salt. Can I use the password as salt? Can I re-use the IV as salt? Maybe not, but I don't want to add another parameter.

不,盐需要是唯一的,最好是随机的;密码/盐组合应该是唯一的(它不应该重复,甚至不在时间上,或在不同的域)。

  1. Can I use a fixed IV? Same plaintext and password should result in different cipher text, so I have to supply the IV for decryption in the payload.

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

  1. Can I use a salt for the key and keep the IV constant instead? Feels wrong.

这是可以的,只要你不重复撒盐。

  1. Creating a nonce and deriving IV and key salt from it is a valid approach?

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

  1. If .Net would support the GCM mode would I still have this problems?

当然可以,从某种意义上说,如果您使用 GCM,您的问题会更糟,因为使用具有相同密钥和 IV 的 GCM 会完全损坏。


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