为什么使用 .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)。我不是加密专家,为什么我必须编写代码?我可能做错了什么...
- 要从密码中导出密钥,接口需要加盐。我可以使用密码作为盐吗?我可以重复使用 IV 作为盐吗?也许不是,但我不想添加另一个参数。
- 我可以使用固定 IV 吗?相同的明文和密码应该会产生不同的密文,所以我必须在有效负载中提供用于解密的 IV。
- 我可以对密钥使用盐并保持 IV 不变吗?感觉不对。
- 创建随机数并从中导出 IV 和密钥盐是一种有效的方法吗?
- 如果 .Net 支持 GCM 模式,我还会遇到这个问题吗?
.NET 加密 API 公开了一个 通用 加密库,其中包含用于实现加密 算法 的面向对象的方法。当然,要使用这些算法和算法实现,你需要对密码学有很好的掌握,而这正是你目前所缺乏的。
需要这个通用库来实现现有的各种协议。通常,单个算法不能满足特定的用例(在您的情况下,使用密码加密字符串,返回不同的字符串)。因此,需要选择或设计一个协议来满足该用例。该协议可以例如定义容器格式,例如 CMS 或 PGP,例如可用于加密电子邮件(用例)。
您正在直接尝试应用加密算法来解决您的用例。那是行不通的。你需要一个 pre-made 协议 ,最好是 pre-made API.
请注意,有许多不同的用例、许多不同的协议以及关于如何正确创建和实施这些协议的更多意见。例如,Libsodium / NaCl 定义了一种名为 SecretBox
的小型容器格式,它确实可以代替您完成一些工作。
但是,在 NaCl 之上实现 TLS 当然是不可能的,因为功能/算法不存在。同样,.NET 需要像 .NET API 这样的通用加密库,供其他人实现他们的协议。
因此,要么你必须硬着头皮尝试创建你自己的协议,要么你采用现有的协议并进行有根据的猜测它是否安全(希望该协议已经过几次审查/更新) .远离没有额外贡献者的单人项目(比如许多未经审查的示例代码)。
你自己的协议,是的,有没有用密文存储salt之类的错误。你需要一个随机的 - 或者至少是唯一的 - salt 来确保安全,为此重复使用密码肯定 不 安全。不要让它本身成为一个人的项目,要么借用协议,要么让其审查。
好的,那快点:
- 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.
不,盐需要是唯一的,最好是随机的;密码/盐组合应该是唯一的(它不应该重复,甚至不在时间上,或在不同的域)。
- 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 应该是不可预测的 除非 你每次都使用新的密钥。
- Can I use a salt for the key and keep the IV constant instead? Feels wrong.
这是可以的,只要你不重复撒盐。
- Creating a nonce and deriving IV and key salt from it is a valid approach?
这取决于非常具体的细节。换句话说,如果你不知道自己在做什么,我不会尝试。
- If .Net would support the GCM mode would I still have this problems?
当然可以,从某种意义上说,如果您使用 GCM,您的问题会更糟,因为使用具有相同密钥和 IV 的 GCM 会完全损坏。
请记住,GCM 只是一种算法,而不是协议,它无法单独解决您的用例。
在大多数情况下,我需要用密码加密一个字符串,然后 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)。我不是加密专家,为什么我必须编写代码?我可能做错了什么...
- 要从密码中导出密钥,接口需要加盐。我可以使用密码作为盐吗?我可以重复使用 IV 作为盐吗?也许不是,但我不想添加另一个参数。
- 我可以使用固定 IV 吗?相同的明文和密码应该会产生不同的密文,所以我必须在有效负载中提供用于解密的 IV。
- 我可以对密钥使用盐并保持 IV 不变吗?感觉不对。
- 创建随机数并从中导出 IV 和密钥盐是一种有效的方法吗?
- 如果 .Net 支持 GCM 模式,我还会遇到这个问题吗?
.NET 加密 API 公开了一个 通用 加密库,其中包含用于实现加密 算法 的面向对象的方法。当然,要使用这些算法和算法实现,你需要对密码学有很好的掌握,而这正是你目前所缺乏的。
需要这个通用库来实现现有的各种协议。通常,单个算法不能满足特定的用例(在您的情况下,使用密码加密字符串,返回不同的字符串)。因此,需要选择或设计一个协议来满足该用例。该协议可以例如定义容器格式,例如 CMS 或 PGP,例如可用于加密电子邮件(用例)。
您正在直接尝试应用加密算法来解决您的用例。那是行不通的。你需要一个 pre-made 协议 ,最好是 pre-made API.
请注意,有许多不同的用例、许多不同的协议以及关于如何正确创建和实施这些协议的更多意见。例如,Libsodium / NaCl 定义了一种名为 SecretBox
的小型容器格式,它确实可以代替您完成一些工作。
但是,在 NaCl 之上实现 TLS 当然是不可能的,因为功能/算法不存在。同样,.NET 需要像 .NET API 这样的通用加密库,供其他人实现他们的协议。
因此,要么你必须硬着头皮尝试创建你自己的协议,要么你采用现有的协议并进行有根据的猜测它是否安全(希望该协议已经过几次审查/更新) .远离没有额外贡献者的单人项目(比如许多未经审查的示例代码)。
你自己的协议,是的,有没有用密文存储salt之类的错误。你需要一个随机的 - 或者至少是唯一的 - salt 来确保安全,为此重复使用密码肯定 不 安全。不要让它本身成为一个人的项目,要么借用协议,要么让其审查。
好的,那快点:
- 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.
不,盐需要是唯一的,最好是随机的;密码/盐组合应该是唯一的(它不应该重复,甚至不在时间上,或在不同的域)。
- 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 应该是不可预测的 除非 你每次都使用新的密钥。
- Can I use a salt for the key and keep the IV constant instead? Feels wrong.
这是可以的,只要你不重复撒盐。
- Creating a nonce and deriving IV and key salt from it is a valid approach?
这取决于非常具体的细节。换句话说,如果你不知道自己在做什么,我不会尝试。
- If .Net would support the GCM mode would I still have this problems?
当然可以,从某种意义上说,如果您使用 GCM,您的问题会更糟,因为使用具有相同密钥和 IV 的 GCM 会完全损坏。
请记住,GCM 只是一种算法,而不是协议,它无法单独解决您的用例。