我正在实现一个非对称加密系统:
''' <summary>
''' A facade for a data asymmetrical encryption algorithm relying on a pair of public and private keys.
''' </summary>
Public Interface IAsymEncrypter
''' <summary>
''' The public key to rely upon for encrypting data. Under XML format.
''' </summary>
ReadOnly Property PublicKeyXml As String
''' <summary>
''' The private key to rely upon for decrypting data. Under XML format.
''' <para>Also contains the public key.</para>
''' </summary>
ReadOnly Property PrivateKeyXml As String
''' <summary>
''' Encrypts data, using a public key.
''' </summary>
''' <param name="Data">The data to encrypt.</param>
Function Encrypt(Data As Byte()) As Byte()
''' <summary>
''' Decrypts data, using a private key.
''' </summary>
''' <param name="Cipher">The cipher to decrypt the data from.</param>
Function Decrypt(Cipher As Byte()) As Byte()
End Interface
该实现包装了一个RSACryptoServiceProvider
。 Encrypt
和 Decrypt
的实现需要选择填充。我已经研究并了解以下内容:
- OAEP 填充应优先于 PKCS。
- 迄今为止,与 OAEP 相关的哈希算法在防止冲突方面的弱点尚未引起关注,也不应成为决定性标准。
- 依靠较短的输出哈希可以加密较大的字符串。
我正在寻找最佳的安全实践,同时保持尽可能低的维护。我看到 .Encrypt
有两个 overloads :
.Encrypt(Data as Byte(), fOAEP as Boolean) as Byte()
,其中fOAEP
应设置为True
依靠 OAEP。我认为这意味着哈希算法是自动选择的;我不知道依据什么标准。.Encrypt(Date as Byte(), Padding as RsaEncryptionPadding) as Byte()
,其中可以指定与 SHA-1 到 SHA512 关联的 OAEP。
两个问题:
- 填充模式是否与加密消息一起存储?也就是说,我可以从加密消息中猜测使用哪种填充模式来解密它吗?
- 如果不是,那么我想我最好自己选择模式,在这种情况下我想知道是否还有其他需要考虑的因素?
最佳答案
I assume this means the hash algorithm is chosen automatically; upon which criteria, that I did not figure out.
不幸的是,旧的 Microsoft API 的详细说明严重不足(或者说文档记录不足)。这并不是唯一找不到算法或编码方法的地方。 SHA-1 是标准中的默认值,因此如果您不指定它,可能会使用它(也是为了向后兼容)。
Q1: Is the padding mode stored alongside the encrypted message? That is, can I guess from an encrypted message which padding mode to use to decrypt it?
不,即使是,您也不应该使用它。 RSA PKCS#1 指定您应该预先确定配置参数。除此之外,如果您在不首先验证该选择的情况下允许更改,那么您会给攻击者带来一点优势。
Q2: If no, then I guess I am better off choosing the mode myself, in which case I would like to know if there are other considerations I should take into account?
SHA-1 是标准中的默认值,可以使用 SHA-256,因为它相对较快且没有任何攻击。它也在最新的 CPU 上得到加速。缺点:如果没有加速,它仍然是 64 位机器上最慢的哈希(但是,与 RSA 相比,它在实践中可能不会那么明显)。 SHA-512 既非常快速又安全,尽管安全裕度对于这个特定目的来说实际上并不重要。
如果存在遗留问题,我只会选择 SHA-1 - 在这种情况下,SHA-1 必须严重损坏才会引起关注。否则 SHA-256 更有意义,因为它显着更安全。
请务必使用扩展方法,这样其他开发人员就不必像您现在一样摸不着头脑。这里有很多问题,人们无法在不同的运行时复制算法。如果您明确指定配置参数,那么您就消除了很多不确定性。
微软并不孤单。糟糕的 API 文档(尽管我必须说,他们在这方面确实很出色)。我很大程度上反对使用密码学的默认值,如果您必须自己记录它,您不妨在代码中指定配置参数。
当我们讨论隐藏基本细节时,您是否担心在 Facade 类中隐藏了所有细节?一般来说,这些类只是 Microsoft 指定 API 周围的一个薄层,它们准确地隐藏了您不想隐藏的细节。如果它们在多个项目中使用,那么如果您犯了任何错误,则几乎不可能更改它们。
通常,创建此类类只是为了包装开发人员的知识,而不是具有特定于应用程序的目的。出于练习目的编写它们很好,但我不会在常规代码库中使用它们。相反,为特定用例编写类。
如果您担心您的消息不适合单个 RSA block ,通常您会使用混合加密并加密随机 AES key 。其他运行时可能会使用原始 RSA 来实现 RSA-KEM,但这在 Microsoft/.NET 环境中可能不是一个好主意,因为您总是需要填充。
关于.net - RSA 和 OAEP : Choosing or not choosing the Hash Algorithm?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60095609/