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

标签 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. 要从密码中派生 key ,接口(interface)需要加盐。我可以使用密码作为盐吗?我可以将静脉注入(inject)液作为盐重复使用吗?也许不是,但我不想添加另一个参数。
  2. 我可以使用固定 IV 吗?相同的明文和密码应该会产生不同的密文,因此我必须在有效负载中提供用于解密的 IV。
  3. 我可以使用盐作为 key 并保持 IV 恒定吗?感觉不对。
  4. 创建一个随机数并从中派生 IV 和 key 盐是一种有效的方法吗?
  5. 如果 .Net 支持 GCM 模式,我还会遇到这个问题吗?

最佳答案

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

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

您直接尝试应用加密算法来解决您的用例。那是行不通的。您需要一个预制的协议(protocol),最好带有预制的 API。


请注意,有许多不同的用例、许多不同的协议(protocol),甚至有更多关于如何正确创建和实现这些协议(protocol)的意见。例如,Libsodium/NaCl 定义了一种名为 SecretBox 的小型容器格式,它确实需要您完成一些工作。

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


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

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


好的,那么快点:

  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 应该是不可预测的,除非您每次都使用新的 key 。

  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,您的问题会更糟,因为使用具有相同 key 和 IV 的 GCM 完全被破坏了。


请记住,GCM 只是一种算法,而不是协议(protocol),它本身无法解决您的用例。

关于c# - 为什么 .Net Framework 的加密如此复杂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56126016/

相关文章:

c# - 为什么我的接口(interface)的 BaseType 为空?

.net - "Error: One or more projects in the solution were not loaded correctly"尤其适用于Windows7

c# - 为什么 C# 在实现接口(interface)时不允许继承返回类型

python - python中的pycrypto和crypto包有什么区别?

.net - 哪种内置 .NET 加密算法最安全?

android - 如果我从应用程序 A 将私钥存储在 KeyStore 中,是否可以从应用程序 B 检索相同的 key ?

c# - 复制大型 (120+GB) 文件时速度变慢

c# - 使用 while 或 for? 查找 array 中的最大数字?

c# - .NET : How to get time for keypress as precisely as possible?

c# - 转发泛型类型定义