.NET RSA CreateEphemeralKey vs PersistKeyInCsp



我正在尝试了解有关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

如果在CspParameters结构中将密钥容器名称保留为null(并且不断言UseDefaultKeyContainer),则会为您断言CreateEphemeralKey标志。

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

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

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

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

是。

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

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

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

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

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

最新更新