I am creating a tool for managing RSA key pairs on Windows, because there are no built-in functions for this, and we widely use RSA encryption functions in .NET.
The tool provides various functions, such as listing existing RSA key pairs, creating new keys, deleting keys, exporting keys, and importing keys from a previously created XML export (exported using ASPNet_RegIIS.exe).
I have all the functions that work separately from importing only public keys for encryption operations. When key pairs are initially created on the servers, both public and public / private export is done in xml using aspnet_regiis.exe .
I try to provide the ability to encrypt configuration files on other machines to prevent the distribution of private keys, if absolutely necessary.
Each time I import a public key from an exported previoulsy XML block, the PublicOnly property for RSACryptoServiceProvider set to false, indicating that the key pair has a public and private key. I have confirmed that xml does not contain secret key information, so the problem is not in the xml file.
The problem occurs when using the CspParameters object and defining the flags as CspProviderFlags.UseMachineKeyStore . If you build RSACryptoServiceProvider without specifying any Csp parameters and then import the key from xml, the PublicOnly property will be correctly set to false.
String xmlText = File.ReadAllText(filePath); RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); csp.FromXmlString(xmlText);
However, since I need to tell it the container key so that it can be used later for encryption operations, I have to use the CspParameters object when building the RSACryptoServiceProvider , since there is no other way to name the container key.
String xmlText = File.ReadAllText(filePath); CspParameters cspParams = new CspParameters(); cspParams.Flags = CspProviderFlags.UseMachineKeyStore; cspParams.KeyContainerName = keyContainerName; RSACryptoServiceProvider csp = new RSACryptoServiceProvider(cspParams); csp.PersistKeyInCsp = true; csp.FromXmlString(xmlText);
I tried various versions of this code, however the problem remains. I note that there are similar questions, such as the RSA Encryption public key not returned from the container? However, I believe that this problem is different, and a satisfactory answer was not provided.
The question is, how can I import the RSA public key from XML and give the key container a name, while in the container there is only a pair of public keys?
EDIT
Further research in this area also shows a problem when importing a full key from xml, as well as setting flags to export the key.
CspProviderFlags.UseArchivableKey;
When this flag is specified in the CSP parameter object, an exception of type "Invalid flags" is csp.FromXmlString(xmlText) in the line csp.FromXmlString(xmlText) ;
I really can't explain it. The key was created and previously exported to XML, of course, if the key was previously exported, could it be imported and allowed to be exported again?
I have done a lot of research on this, but I just don’t see an answer to any of these problems.
I tried changing the csp provider type from PROV_RSA_FULL to PROV_RSA_AES, since I believe that this is now the default value, and I believed that the keys were originally created using this instead of PROV_RSA_FULL, but that didn’t make any difference.