简体   繁体   English

如何有效地恢复 RSA 中的公钥或私钥?

[英]How to efficiently restore public or private key in RSA?

I found many posts how to do that via RSACryptoServiceProvider but all of them missing one maybe minor thing.我发现很多帖子如何通过 RSACryptoServiceProvider 做到这一点,但他们都错过了一件可能是次要的事情。 Even though it is minor I would like to ask if anybody knows how to do it efficiently.即使它是次要的,我想问是否有人知道如何有效地做到这一点。

When you instantiate RSACryptoServiceProvider, it generates a private/public key.当您实例化 RSACryptoServiceProvider 时,它会生成一个私钥/公钥。 There are import methods on the object allowing you to import another key. object 上有一些导入方法允许您导入另一个密钥。 ImportCspBlob for example.以 ImportCspBlob 为例。 What bothers me is that it generates the private/public key pair while executing the constructor even though I don't need them.困扰我的是,即使我不需要它们,它也会在执行构造函数时生成私钥/公钥对。 I plan to import another key anyway.无论如何,我计划导入另一个密钥。 The question is how to either avoid generating of the keys when executing a constructor or pass my key into the constructor effectively avoiding generating of a new pair?问题是如何在执行构造函数时避免生成密钥或将我的密钥传递给构造函数,从而有效地避免生成新的对?

Also, I'm aware about the key container and read about how to use it passing CspParameters to the constructor but in my case I pass a public key to another app or system that means the container is empty anyway.另外,我知道密钥容器并阅读了有关如何使用它将 CspParameters 传递给构造函数的信息,但在我的情况下,我将公钥传递给另一个应用程序或系统,这意味着容器无论如何都是空的。

The RSACryptoServiceProvider constructor does create a key pair according to the short constructor documentation: RSACryptoServiceProvider构造函数确实根据简短的构造函数文档创建了一个密钥对:

Initializes a new instance of the RSACryptoServiceProvider class with a random key pair.使用随机密钥对初始化RSACryptoServiceProvider class 的新实例。

However, if you click on the constructor and then read the full documentation then below even the example code you get this sentence:但是,如果您单击构造函数,然后阅读完整的文档,那么即使在示例代码下方,您也会得到这句话:

This constructor does not generate a new public/private keypair immediately .此构造函数不会立即生成新的公钥/私钥对。 If no key is loaded via the ImportParameters method, or any other key import method, before a key is needed then a 1024-bit ephemeral key is created on demand.如果没有通过ImportParameters方法或任何其他密钥导入方法加载密钥,则在需要密钥之前,会按需创建一个 1024 位的临时密钥。

In other words, it uses lazy instantiation of the key pair fields.换句话说,它使用密钥对字段的惰性实例化。

So your assumption is wrong but you've got a pretty big excuse for getting it wrong: the documentation of the .NET crypto classes is still not at the level that it should be.所以你的假设是错误的,但你有一个很大的借口来犯错:.NET 加密类的文档仍然没有达到应有的水平。

Documentation is not clear on this account but it looks like the key pair is actually created in the constructor.该帐户的文档尚不清楚,但看起来密钥对实际上是在构造函数中创建的。 Here is the constructor这是构造函数

    [SecurityCritical]
private RSACryptoServiceProvider(
  int dwKeySize,
  CspParameters parameters,
  bool useDefaultKeySize)
{
  if (dwKeySize < 0)
    throw new ArgumentOutOfRangeException(nameof (dwKeySize), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
  this._parameters = Utils.SaveCspParameters(CspAlgorithmType.Rsa, parameters, RSACryptoServiceProvider.s_UseMachineKeyStore, ref this._randomKeyContainer);
  this.LegalKeySizesValue = new KeySizes[1]
  {
    new KeySizes(384, 16384, 8)
  };
  this._dwKeySize = useDefaultKeySize ? 1024 : dwKeySize;
  if (this._randomKeyContainer && !Environment.GetCompatibilityFlag(CompatibilityFlag.EagerlyGenerateRandomAsymmKeys))
    return;
  this.GetKeyPair();
}

At the end it calls GetKeyPair.最后它调用GetKeyPair。 Eventually it calls GetKeyPairHelper and in the middle of that method I see最终它调用 GetKeyPairHelper 并在该方法的中间我看到

      int userKey = Utils._GetUserKey(safeProvHandle, parameters.KeyNumber, ref invalidHandle);
  if (userKey != 0)
  {
    if ((parameters.Flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags || userKey != -2146893811)
      throw new CryptographicException(userKey);
    Utils._GenerateKey(safeProvHandle, parameters.KeyNumber, parameters.Flags, dwKeySize, ref invalidHandle);
  }

Pay attention to the Utils._GenerateKey.注意 Utils._GenerateKey。 That makes me believe that at least in certain cases it generates the key.这让我相信至少在某些情况下它会生成密钥。 It is not exactly clear to me which block of the code is executed in my particular conditions and my example can be completely out of the context.我不清楚在我的特定条件下执行哪个代码块,我的示例可能完全脱离上下文。 I'm trying to understand then how exactly I have to write the code to guarantee the key pair is not created in the constructor.我试图了解我必须如何编写代码以保证密钥对不在构造函数中创建。

Also this documentation https://docs.microsoft.com/en-us/dotnet/standard/security/generating-keys-for-encryption-and-decryption says此文档https://docs.microsoft.com/en-us/dotnet/standard/security/generating-keys-for-encryption-and-decryption还说

A public/private key pair is generated whenever a new instance of an asymmetric algorithm class is created.每当创建非对称算法 class 的新实例时,都会生成公钥/私钥对。

So, everything is rather confusing.所以,一切都相当混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM