RSA 和 OAEP:选择还是不选择哈希算法?

RSA and OAEP: Choosing or not choosing the Hash Algorithm?

我正在实施非对称加密系统:

''' <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

实现包装了一个 RSACryptoServiceProviderEncryptDecrypt 的实现需要选择填充。我已经研究并了解以下内容:

我正在寻找最佳安全实践,同时尽可能降低维护成本。我看到 .Encrypt 有两个 overloads:

两个问题:

  1. 填充模式是否与加密消息一起存储?也就是说,我可以从加密消息中猜测使用哪种填充模式来解密它吗?
  2. 如果没有,那么我想我还是自己选择模式比较好,这样的话我想知道是否还有其他需要考虑的因素?

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 更有意义,因为它相当更安全。


请务必使用扩展方法,这样其他开发人员就不必像您现在这样挠头了。这里有很多问题,人们无法在不同的运行时复制算法。如果您清楚地指定配置参数,那么您就消除了很多不确定性。

Microsoft 并不孤单w.r.t。糟糕的 API 文档(尽管他们在其中 excel,我必须说)。我主要反对使用密码学的默认值,如果你必须自己记录它,你还不如在代码中指定配置参数。


当我们讨论隐藏基本细节时,您不担心您将所有细节都隐藏在 Facade class 中吗?一般来说,这些 classes 只是 Microsoft 指定的 API 周围的薄层,它们恰好隐藏了您不想隐藏的细节。如果它们在多个项目中使用,如果您犯了任何错误,几乎不可能更改它们。

一般来说,这些 classes 的创建只是为了 总结开发人员的知识 而不是具有特定于应用程序的目的。出于练习目的编写它们很好,但我不会在您的常规代码库中使用它们。相反,针对特定用例编写 classes


如果您担心您的消息不适合单个 RSA 块,通常您会使用混合密码术并加密随机 AES 密钥。其他运行时可能会使用原始 RSA 来实现 RSA-KEM,但这在 Microsoft / .NET 环境中可能不是一个好主意,因为您总是需要填充。