3

我正在尝试更多地了解 RSA 在 .NET 中的功能,并遇到了这篇有用的帖子,该帖子表明默认情况下密钥存储在 Windows 中: https ://stackoverflow.com/a/5845191/1181412

我的问题参考了下面的示例代码。假设意图是仅在应用程序会话的生命周期内生成一次性密钥。

问题 1:在下面的结构中,是否每次在类中的任何位置创建 RSACryptoServiceProvider 时都需要将 PersistKeyInCsp 标志设置为 false,即使它正在访问同一个 CspParameters 对象?

问题 2:在 CspParameters 对象上设置 CreateEphemeralKey 标志是否取代了在此示例中使用 PersistKeyInCsp 的需要?

Public Class RSACrypto

    Private RSAKey As CspParameters

    Public Sub New(KeySize As Integer)
        MyBase.New()
        RSAKey = New CspParameters
        Using RSA As New RSACryptoServiceProvider(KeySize, RSAKey)
            RSA.PersistKeyInCsp = False
        End Using
    End Sub

    Public Function PublicKey() As Byte()
        Using RSA As New RSACryptoServiceProvider(RSAKey)
            RSA.PersistKeyInCsp = False
            Return RSA.ExportCspBlob(False)
        End Using
    End Function
End Class
4

1 回答 1

0

CreateEphemeralKey如果您将密钥容器名称保留null在 CspParameters 结构中(并且您没有 assert UseDefaultKeyContainer) ,则该标志会为您声明。

对于使用CreateEphemeralKey(或通过null名称隐式创建)的键,该PersistKeyInCsp属性没有意义或效果。对于命名(持久)键,它会在对象被处置或最终确定时从磁盘中删除该键。(注意异常终止意味着密钥永远不会被删除)

问题 1:在下面的结构中,是否每次在类中的任何位置创建 RSACryptoServiceProvider 时都需要将 PersistKeyInCsp 标志设置为 false,即使它正在访问同一个 CspParameters 对象?

如果密钥在您第一次设置PersistKeyInCsp=false和调用Dispose()(直接或通过using语句)时被持久化,或者让密钥被垃圾收集并最终确定,那么后续访问将失败或创建不同的密钥(取决于UseExistingKey标志是否断言)。所以,说“不,你不应该那样做”是最正确的。

问题 2:在 CspParameters 对象上设置 CreateEphemeralKey 标志是否取代了在此示例中使用 PersistKeyInCsp 的需要?

是的。

隐含问题 3:为什么我的代码不起作用?

在您的构造函数中,您具有以下三种行为之一,具体取决于 的值CspParameters.KeyContainerName和系统状态:

  • KeyContainerName == null
    • 您创建了一个 size 的临时密钥KeySize。然后将其丢弃。没有人会知道你的钥匙是什么。
  • 命名键不存在:
    • 您生成了一个大小为 的密钥对KeySize,将其保存到磁盘,然后将其删除。没有人会知道你的钥匙是什么。
  • 命名键确实存在:
    • 您打开了密钥对(KeySize被忽略)。然后你把它从磁盘上删除了。希望你不需要它。

在您的PublicKey方法中,您可以创建一个 1024 位临时密钥(如果RSAKey.KeyContainerName == null)或打开一个现有密钥,或者生成一个 1024 位密钥并将其保存到磁盘。然后导出公钥的 CAPI blob,并(如果是临时的)丢弃密钥或(如果持久)将其从系统中删除。(1024 位是因为您使用了没有 keysize 值的 CspParameters ctor,所以KeySize来自 ctor 的值无关紧要)

您可能想要的不是保存 CspParameters,而是实际的 RSA / RSACryptoServiceProvider 对象。

于 2017-12-22T16:08:08.993 回答