1

I have DER encoded RSA keypair created in Crypto++, as well as cipher. They are Base64Encoded string. I first decode the data from Base64 to byte array, but I am not sure how to load them into RSACryptoServiceProvider.

static void Main()
{
    string pbkeystr = "mypublickey";
    string pvkeystr = "myprivatekey";
    string cipherstr = "mycipher";

    byte[] pbkey = Convert.FromBase64String(pbkeystr);
    byte[] pvkey = Convert.FromBase64String(pvkeystr);
    byte[] cipher = Convert.FromBase64String(cipherstr);

    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

    //Set keys here..

    //Decrypt the cipher using private key
    rsa.Decrypt(pvkey, false);
}

There are no functions to set keys. The only thing I found was ImportParameters method, which takes RSAParameters class which consists of p, q, n, modulus, exponent etc. I don't have access to these.

Is there any way I can load the keys as string? How can I load the key into RSACryptoServiceProvider?

jww
  • 97,681
  • 90
  • 411
  • 885
Kyojin
  • 157
  • 2
  • 12

1 Answers1

1

Is there any way I can load the keys as string? How can I load the key into RSACryptoServiceProvider?

From your other Crypto++ question, How to load Base64 RSA keys in Crypto++, it looks like you have only the public and private keys because you used DEREncode and BERDecode. That is, you have the RSA parameters, and not the subject public key info and the private key info. Your keys lack the OID identifiers and version numbers. Things are fine that way.

From Cryptographic Interoperability: Keys on the Code Project, you will need a C# class that parses the ASN.1/DER after you Base64 decode it. The CodeProject article provides a C# class called AsnKeyParser to read the ASN.1/DER and returns a RSAParameters to load into a CSP.

The code for the AsnKeyParser class is about 800 lines, and there are five other supporting files to make it all happen, so its not really appropriate to place it here. You should download it yourself. The file of interest is called CSInteropKeys.zip.

Once you wire-in the AsnKeyParser class, it will be as simple as the following for a RSA Public key. The private key will be similar, and the code is given on the CodeProject site.

// Your ASN.1/DER parser class
AsnKeyParser keyParser = new AsnKeyParser("rsa-public.der");
RSAParameters publicKey = keyParser.ParseRSAPublicKey();

// .Net class
CspParameters csp = new CspParameters;
csp.KeyContainerName = "RSA Test (OK to Delete)";    
csp.ProviderType = PROV_RSA_FULL;    // 1
csp.KeyNumber = AT_KEYEXCHANGE;      // 1

// .Net class
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp);
rsa.PersistKeyInCsp = false;
rsa.ImportParameters(publicKey);

Linking to files on another site is frowned upon, but I don't know how to provide the information otherwise. There's too much source code involved to place in an answer.


For completeness, .Net does not make interop easy. They do not accept ASN.1/DER or PEM. Rather, .Net accepts some XML representation of the keys. I believe you can find it in RFC 3275, XML-Signature Syntax and Processing. Microsoft does not state that for you. I kind of pieced it together when I wrote the Code Project article.

Maybe we should add a class to Crypto++ to regurgitate XML in addition to ASN.1/DER and PEM.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • Okay, what I did was I read the Base64 string and converted it to byte data (Converted from Base64 back to the originally DEREncoded bytes). Wrote it down to a file called "rsa-private.der" and passed it to the AsnKeyParser as in your example, but I get exception: CryptographicException: Parameter was invalid. http://pastebin.com/hLwErEfp What did I do wrong? – Kyojin Feb 11 '17 at 13:52
  • @Kyojin - From your notes on the PasteBin, it looks like the exception occurs at `var data = rsp.Decrypt(cipherArr, false)`. Is that correct? If so, I believe that means the private key loaded as expected. I'm guessing the problem is either `csp.KeyNumber = AT_KEYEXCHANGE` or its you RSA padding. Maybe you can try [`Decrypt Method (Byte[], RSAEncryptionPadding)`](https://msdn.microsoft.com/en-us/library/mt132683(v=vs.110).aspx). If its more than padding, then you should probably ask a new question. Stack Overflow likes to keep questions and answers narrow in scope. – jww Feb 11 '17 at 14:01
  • Yes, I did rsa.ToXmlString() and checked the and everything is correct and the same as the base64 string in the file. So why it didn't decrypt the cipher? Guess that's offtopic now. – Kyojin Feb 11 '17 at 14:05
  • @Kyojin - *" So why it didn't decrypt the cipher?"* - I'm guessing (and its only a guess) that the padding is different. When you ask a new question, be sure to state the Crypto++ classes you used for encryption (a relevant snippet is fine), and then show the C# code that is failing (again, a snippet is fine). That way, we can line things up in C++ and C#. Deep diving your next problem means *this* question is no longer *"How can I load the key into RSACryptoServiceProvider?"* – jww Feb 11 '17 at 14:18
  • There is a reasonably short way of parsing just the public key to get an instance of `RSACryptoServiceProvider`; https://stackoverflow.com/a/49416370/1838819 – DiskJunky Mar 23 '18 at 15:28