简体   繁体   中英

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. 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. There are import methods on the object allowing you to import another key. ImportCspBlob for example. 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.

The RSACryptoServiceProvider constructor does create a key pair according to the short constructor documentation:

Initializes a new instance of the RSACryptoServiceProvider class with a random key pair.

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.

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.

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. Eventually it calls GetKeyPairHelper and in the middle of that method I see

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

A public/private key pair is generated whenever a new instance of an asymmetric algorithm class is created.

So, everything is rather confusing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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