5

As a part of my project I have to encrypt some text with RSA and I have got a public key from another company. The public key looks like this:

var publicKey="MIGfMA0GCSq2GSIb3DQEBAQUAA4GNADCBiQKBgQCgFGVfrY4jQSoZQWWygZ83roKXWD4YeT2x2p41dGkPixe73rT2IW04glatgN2vgoZsoHuOPqah5and6kAmK2ujmCHu6D1auJhE2tXP+yLkpSiYMQucDKmCsWXlC5K7OSL77TXXcfvTvyZcjObEz6LIBRzs6+FqpFbUO9SJEfh6wIDAQAB" 

The problem is that I don't know what is its format and how to deserialize it to RSAParameters. Other examples on the Internet have used XML serialization. The key is created by Java.

Then I also want to know how to deserialize its related private key which I don't have access to any sample of it right now.

Update :

Here is part of my code :

var pk = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiiTx4F35eWP10AFMAo8MLhCKq2ryKFG9PKKWeMLQuwMSdiQq347BkMYA+Q+YscScf7weUSTk9BHVNNfTchDwzjQrIoz6TZGggqD+ufin1Ccy0Sp6QeBMnIB89JsdzQGpVcsoTxk53grW0nYY8D+rlFvBwFicKe/tmVPVMYsEyFwIDAQAB";

...

public static RSACryptoServiceProvider ImportPublicKey(string pem)
{
    //var newPem = "-----BEGIN PUBLIC KEY-----\n" + pem + "-----END PUBLIC KEY-----";
    Org.BouncyCastle.OpenSsl.PemReader pr = new Org.BouncyCastle.OpenSsl.PemReader(new StringReader(Pem));
    Org.BouncyCastle.Crypto.AsymmetricKeyParameter publicKey = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pr.ReadObject();
    RSAParameters rsaParams = Org.BouncyCastle.Security.DotNetUtilities.ToRSAParameters((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)publicKey);

    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
    csp.ImportParameters(rsaParams);
    return csp;
}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
nAviD
  • 2,784
  • 1
  • 33
  • 54
  • looks like base 64 string – Legacy Code Jul 26 '20 at 16:41
  • It seems to be Base64. But what was its actual data before becoming base64 and how to convert it to RSAParameters? – nAviD Jul 26 '20 at 16:51
  • if it is a base64 string you can do the following byte[] data = Convert.FromBase64String(encodedString); string decodedString = Encoding.UTF8.GetString(data); – Alireza Yadegari Jul 26 '20 at 17:06
  • 2
    This is a public key in X.509 (SPKI) format in PEM encoding (without header and footer). The processing depends on the .NET version. Which .NET version do you use? – Topaco Jul 26 '20 at 17:16
  • @Topaco .NET Framework 4.6 – nAviD Jul 26 '20 at 17:33
  • 1
    One option is BouncyCastle. The `ImportPublicKey` method in [this example](https://gist.github.com/valep27/4a720c25b35fff83fbf872516f847863) expects an X.509 (SPKI) key with PEM encoding (including header and footer) and fills an `RSAParameters` object (among other things) . – Topaco Jul 26 '20 at 21:30
  • @Topaco it throrws null reference exception on the line 3 of the method because the publicKey variable is null althoghe the pem var is not. – nAviD Jul 27 '20 at 05:33
  • Without code, trouble shooting is difficult. I suspect that the PEM key is not formatted correctly. You have to add header (`-----BEGIN PUBLIC KEY-----`) and footer (`-----END PUBLIC KEY-----`) in a _separate_ line, i.e. after the header and before the footer a line break is necessary. If you still have problems, please edit your question and post your code including the key as it is used in the code. – Topaco Jul 27 '20 at 06:09
  • @Topaco it did not worked either. I provided the actual pk as you said. – nAviD Jul 27 '20 at 06:44
  • The line break _before_ the footer is still missing: `var Pem = "-----BEGIN PUBLIC KEY-----\n" + pem + "\n-----END PUBLIC KEY-----";`! – Topaco Jul 27 '20 at 07:06
  • @Topaco Thank you very much. Please provide an answer so I can mark it as the answer. – nAviD Aug 01 '20 at 08:36
  • You're welcome. I' ve also posted the desired answer. – Topaco Aug 10 '20 at 06:10

1 Answers1

7

The posted key is a PEM encoded public key in X.509 (SPKI) format, but without header (-----BEGIN PUBLIC KEY-----) and footer (-----END PUBLIC KEY-----). This can be easily verified with an ASN.1 parser, e.g. here.

The import of such a key depends on the .NET version. .NET Core offers from v3.0 on methods that directly support the import of PKCS#1, PKCS#8 and X.509 keys, e.g. RSA.ImportSubjectPublicKeyInfo for the latter. This option is not available for .NET Framework, but BouncyCastle offers a similarly comfortable solution.

Here (see ImportPublicKey method) is an example that imports a PEM encoded public key in X.509 (SPKI) format using BouncyCastle. However, the PemReader used there expects the complete PEM data, including header and footer, both separated from the body by line breaks. Therefore, when using the public keys posted here, header and footer must be added accordingly, e.g:

using System.IO;
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
...
// from: https://gist.github.com/valep27/4a720c25b35fff83fbf872516f847863
public static RSACryptoServiceProvider ImportPublicKey(string pemBody)
{
    var pem = "-----BEGIN PUBLIC KEY-----\n" + pemBody + "\n-----END PUBLIC KEY-----";      // Add header and footer
    PemReader pr = new PemReader(new StringReader(pem));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);

    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
    csp.ImportParameters(rsaParams);
    return csp;
}
Topaco
  • 40,594
  • 4
  • 35
  • 62