Associating an X509Certificate2 certificate with a private key in .NET - c#

I'm trying to create an X509Certificate2 object by using this code: https://stackoverflow.com/a/9250034/5589417
How can I get the private key that corresponds to the certificate's public key?
I have these methods for encryption and decryption:
public static byte[] Encrypt(byte[] plainBytes, X509Certificate2 cert)
{
RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
return encryptedBytes;
}
public static byte[] Decrypt(byte[] encryptedBytes, X509Certificate2 cert)
{
RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
return decryptedBytes;
}
When I use the Decrypt method I get a NullRefereneceException for privateKey.

We have to setup manually PrivateKey property for certificate instance. I also updated code from old answer you linked and removed using of obsolete methods:
static void Main(string[] args)
{
var cert = GenerateCertificate("localhost");
byte[] ciphertext = Encrypt(Encoding.ASCII.GetBytes("Hello world!"), cert);
byte[] plaintext = Decrypt(ciphertext, cert);
Console.WriteLine(Encoding.ASCII.GetString(plaintext));
}
static X509Certificate2 GenerateCertificate(string certName)
{
var secureRandom = new SecureRandom(new CryptoApiRandomGenerator());
var keypairgen = new RsaKeyPairGenerator();
// RSA key size = 1024 bits
keypairgen.Init(new KeyGenerationParameters(secureRandom, 1024));
var keypair = keypairgen.GenerateKeyPair();
var gen = new X509V3CertificateGenerator();
// we will use SHA256 signature
var signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keypair.Private, secureRandom);
var CN = new X509Name("CN=" + certName);
var SN = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(SN);
gen.SetSubjectDN(CN);
gen.SetIssuerDN(CN);
gen.SetNotAfter(DateTime.MaxValue);
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetPublicKey(keypair.Public);
var newCert = gen.Generate(signatureFactory);
var x509cert = new X509Certificate2(DotNetUtilities.ToX509Certificate(newCert));
var rsa = RSA.Create();
var publicKey = (RsaKeyParameters)keypair.Public;
var privateKey = (RsaPrivateCrtKeyParameters)keypair.Private;
var parameters = new RSAParameters
{
Modulus = publicKey.Modulus.ToByteArrayUnsigned(),
Exponent = publicKey.Exponent.ToByteArrayUnsigned(),
P = privateKey.P.ToByteArrayUnsigned(),
Q = privateKey.Q.ToByteArrayUnsigned(),
DP = privateKey.DP.ToByteArrayUnsigned(),
DQ = privateKey.DQ.ToByteArrayUnsigned(),
InverseQ = privateKey.QInv.ToByteArrayUnsigned(),
D = privateKey.Exponent.ToByteArrayUnsigned(),
};
rsa.ImportParameters(parameters);
// at this point X509Certificate2 will check if PrivateKey matches PublicKey
x509cert.PrivateKey = rsa;
return x509cert;
}
public static byte[] Encrypt(byte[] plainBytes, X509Certificate2 cert)
{
RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
return encryptedBytes;
}
public static byte[] Decrypt(byte[] encryptedBytes, X509Certificate2 cert)
{
RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
return decryptedBytes;
}

Related

How to write RSA encrypt function in C#

I have following nodejs code to encrypt RSA:
const encryptWithRSA = (PublicKey, selData) => {
let encrypted = crypto.publicEncrypt(
{
key: -----BEGIN PUBLIC KEY-----\n${PublicKey}\n-----END PUBLIC KEY-----,
padding: crypto.constants.RSA_PKCS1_PADDING,
},
Buffer.from(selData)
);
return encrypted.toString("base64");
};
Then I tried to convert this code block to C# :
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
public static string Encrypt(string publickey, string data)
{
string key = publickey;
Asn1Object obj = Asn1Object.FromByteArray(Convert.FromBase64String(key));
DerSequence publicKeySequence = (DerSequence)obj;
DerBitString encodedPublicKey = (DerBitString)publicKeySequence[1];
DerSequence publicKey = (DerSequence)Asn1Object.FromByteArray(encodedPublicKey.GetBytes());
DerInteger modulus = (DerInteger)publicKey[0];
DerInteger exponent = (DerInteger)publicKey[1];
RsaKeyParameters keyParameters = new RsaKeyParameters(false, modulus.PositiveValue, exponent.PositiveValue);
RSAParameters parameters = DotNetUtilities.ToRSAParameters(keyParameters);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(parameters);
byte[] dataToEncrypt = Encoding.UTF8.GetBytes(data);
byte[] encryptedData = rsa.Encrypt(dataToEncrypt, RSAEncryptionPadding.Pkcs1);
return Convert.ToBase64String(encryptedData);
}
Two code return 2 different results. Anyone can show me what wrong? Thanks!

C# RSA Encryption to PHP Decryption using PHP OpenSSL public key

I'm trying to load a OpenSSL public key from a SOAP server through Nusoap into C#, encrypt my data using the public key, then send the data back to the PHP server for decryption using the private key.
My C# looks like this:
static void Main(string[] args)
{
PHPRef.AddService test = new PHPRef.AddService();
var pkey = test.getPublicKey();
//Console.WriteLine(pkey.ToString());
byte[] PublicKey = GetBytes(pkey);
//Values to store encrypted symmetric keys.
byte[] EncryptedSymmetricKey;
byte[] EncryptedSymmetricIV;
//Create a new instance of RSACryptoServiceProvider.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048);
//Get an instance of RSAParameters from ExportParameters function.
RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey;
//Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
//Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
Console.WriteLine("RijndaelManaged Key and IV have been encrypted with RSACryptoServiceProvider.");
byte[] encryptedData = RSA.Encrypt(GetBytes("password"), false);
//byte[] returned = (byte[])(Array)test.getDecrypted((sbyte[])(Array)encryptedData);
//string answer = GetString(returned);
string answer = test.getDecrypted((sbyte[])(Array)encryptedData);
Console.WriteLine(answer);
Console.ReadLine();
}
static byte[] GetBytes(string str)
{
byte[] bytes = Encoding.ASCII.GetBytes(str);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = Encoding.ASCII.GetChars(bytes);
return new string(chars);
}
And my PHP like so:
function getPublicKey()
{
$crt = file_get_contents("public.crt");
// $publickey = str_ireplace("\r", "", $crt);
// $publickey = str_ireplace("\n", "", $publickey);
// $publickey = str_ireplace("-----BEGIN CERTIFICATE-----", "", $publickey);
// $publickey = str_ireplace("-----END CERTIFICATE-----", "", $publickey);
return $crt;
}
function getDecrypted($input)
{
global $privateRSA;
// $privateRSA = str_ireplace("\r", "", $privateRSA);
// $privateRSA = str_ireplace("\n", "", $privateRSA);
// $privateRSA = str_ireplace("-----BEGIN RSA PRIVATE KEY-----", "", $privateRSA);
// $privateRSA = str_ireplace("-----END RSA PRIVATE KEY-----", "", $privateRSA);
if(!openssl_private_decrypt($input, $decrypted, $privateRSA))
return "fail";
else
return "success";
return $decrypted;
}
Needless to say I get "fail" every time. Any suggestions? I'm trying to do this with pure PHP and pure C#, no special libraries. The keys are 2048 bit.
After nearly a full day trying to find this, it was incredibly simple. You don't need BouncyCastle, SecLib, any third-party libraries, nothing.
C#:
static void Main(string[] args)
{
PHPRef.AddService test = new PHPRef.AddService();
var pkey = test.getPublicKey();
byte[] pkeybyte = GetBytes(pkey);
X509Certificate2 cert = new X509Certificate2();
cert.Import(pkeybyte);
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
byte[] encryptedData = rsa.Encrypt(GetBytes("password"), false);
Console.WriteLine(GetString(encryptedData));
string answer = test.getDecrypted((sbyte[])(Array)encryptedData);
Console.WriteLine(answer);
Console.ReadLine();
}
And the PHP:
Just change getPublicKey like so
function getPublicKey()
{
$crt = file_get_contents("public.crt");
$publickey = str_ireplace("\r", "", $crt);
$publickey = str_ireplace("\n", "", $publickey);
$publickey = str_ireplace("-----BEGIN CERTIFICATE-----", "", $publickey);
$publickey = str_ireplace("-----END CERTIFICATE-----", "", $publickey);
return $publickey;
}

RSA asymmentic encryption exception

I using the following code to generate the public and private key for RSA encryption
public static string RSA_Decrypt(string encryptedText, string privateKey)
{
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
var buffer = Convert.FromBase64String(encryptedText);
byte[] plainBytes = rsaProvider.Decrypt(buffer, false);
string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
return plainText;
}
public static string RSA_Encrypt(string data, string publicKey)
{
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(publicKey));
byte[] plainBytes = Encoding.UTF8.GetBytes(data);
byte[] encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
return Convert.ToBase64String(encryptedBytes);
}
public static Tuple<string, string> CreateKeyPair()
{
CspParameters cspParams = new CspParameters { ProviderType = 1 /* PROV_RSA_FULL */ };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(2048, cspParams);
string publicKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(false));
string privateKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(true));
return new Tuple<string, string>(privateKey, publicKey);
}
the decrypt function return this exception exception
"key does not exist"
please advice me to fix this issue.
This code (using the methods you provided) works fine:
static void Main()
{
var keyPair = CreateKeyPair();
var encryptedText = Encrypt(keyPair.Item2, "test data");
var decryptedText = Decrypt(keyPair.Item1, encryptedText);
Console.WriteLine("Encrypted text: {0}", encryptedText);
Console.WriteLine("Decrypted text: {0}", decryptedText);
}
public static string RSA_Decrypt(string encryptedText, string privateKey)
{
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
var buffer = Convert.FromBase64String(encryptedText);
byte[] plainBytes = rsaProvider.Decrypt(buffer, false);
string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
return plainText;
}
public static string RSA_Encrypt(string data, string publicKey)
{
CspParameters cspParams = new CspParameters { ProviderType = 1 };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(publicKey));
byte[] plainBytes = Encoding.UTF8.GetBytes(data);
byte[] encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
return Convert.ToBase64String(encryptedBytes);
}
public static Tuple<string, string> CreateKeyPair()
{
CspParameters cspParams = new CspParameters { ProviderType = 1 /* PROV_RSA_FULL */ };
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(2048, cspParams);
string publicKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(false));
string privateKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(true));
return new Tuple<string, string>(privateKey, publicKey);
}

Read RSA PrivateKey in C# and Bouncy Castle

I have successfully written to public and private key files with OpenSSL format.
Files:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpHCHYgawzNlxVebSKXL7vfc/i
hP+dQgMxlaPEi7/vpQtV2szHjIP34MnUKelXFuIETJjOgjWAjTTJoj38MQUWc3u7
SRXaGVggqQEKH+cRi5+UcEObIfpi+cIyAm9MJqKabfJK2e5X/OS7FgAwPjgtDbZO
ZxamOrWWL8KGB+lH+QIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCpHCHYgawzNlxVebSKXL7vfc/ihP+dQgMxlaPEi7/vpQtV2szH
jIP34MnUKelXFuIETJjOgjWAjTTJoj38MQUWc3u7SRXaGVggqQEKH+cRi5+UcEOb
Ifpi+cIyAm9MJqKabfJK2e5X/OS7FgAwPjgtDbZOZxamOrWWL8KGB+lH+QIDAQAB
AoGBAIXtL6jFWVjdjlZrIl4JgXUtkDt21PD33IuiVKZNft4NOWLu+wp17/WZYn3S
C2fbSXfaKZIycKi0K8Ab6zcUo0+QZKMoaG5GivnqqTPVAuZchkuMUSVgjGvKAC/D
12/b+w+Shs9pvqED1CxfvtePXNwL6ZNuaREFC5hF/YpMVyg5AkEA3BUCZYJ+Ec96
2cwsdY6HocW8Kn+RIqMjkNtyLA19cQV5mpIP7kAiW6drBDlraVANi+5AgK2zQ+ZT
hYzs/JfRKwJBAMS1g5/B7XXnfC6VTRs8AMveZudi5wS/aGpaApybsfx1NTLLsm3l
GmGTkbCr+EPzvJ5zRSIAHAA6N6NdORwzEWsCQHTli+JTD5dyNvScaDkAvbYFi06f
d32IXYnBpcEUYT65A8BAOMn5ssYwBL23qf/ED431vLkcig1Ut6RGGFKKaQUCQEfa
UdkSWm39/5N4f/DZyySs+YO90csfK8HlXRzdlnc0TRlf5K5VyHwqDkatmoMfzh9G
1dLknVXL7jTjQZA2az8CQG0jRSQ599zllylMPPVibW98701Mdhb1u20p1fAOkIrz
+BNEdOPqPVIyqIP830nnFsJJgTG2eKB59ym+ypffRmA=
-----END RSA PRIVATE KEY-----
And public key contains just the public key portion of course.
After encrypting my message using the public key. I want to read the private key file
and decrypt it but it's not working. I'm getting exceptions trying to read the private key saying can't cast object to asymmetriccipherkey.
Here is my code:
public static AsymmetricKeyParameter ReadAsymmetricKeyParameter(string pemFilename)
{
var fileStream = System.IO.File.OpenText(pemFilename);
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(fileStream);
var KeyParameter = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pemReader.ReadObject();
return KeyParameter;
}
static void Encrypt2(string publicKeyFileName, string inputMessage, string encryptedFileName)
{
UTF8Encoding utf8enc = new UTF8Encoding();
FileStream encryptedFile = null;
try
{
// Converting the string message to byte array
byte[] inputBytes = utf8enc.GetBytes(inputMessage);
// RSAKeyPairGenerator generates the RSA Key pair based on the random number and strength of key required
/*RsaKeyPairGenerator rsaKeyPairGnr = new RsaKeyPairGenerator();
rsaKeyPairGnr.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(new SecureRandom(), 512));
Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair = rsaKeyPairGnr.GenerateKeyPair();
*/
AsymmetricKeyParameter publicKey = ReadAsymmetricKeyParameter(publicKeyFileName);
// Creating the RSA algorithm object
IAsymmetricBlockCipher cipher = new RsaEngine();
// Initializing the RSA object for Encryption with RSA public key. Remember, for encryption, public key is needed
cipher.Init(true, publicKey);
//Encrypting the input bytes
byte[] cipheredBytes = cipher.ProcessBlock(inputBytes, 0, inputMessage.Length);
//Write the encrypted message to file
// Write encrypted text to file
encryptedFile = File.Create(encryptedFileName);
encryptedFile.Write(cipheredBytes, 0, cipheredBytes.Length);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception encrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (encryptedFile != null)
{
encryptedFile.Close();
}
}
}
Here is the decrypt function. 2nd one is without using Bouncy Castle, however, I'd rather use Bouncy Castle since later I'll be also encrypting and decrypting in Java.
static void Decrypt2(string privateKeyFileName, string encryptedFileName, string plainTextFileName)
{
UTF8Encoding utf8enc = new UTF8Encoding();
FileStream encryptedFile = null;
StreamWriter plainFile = null;
byte[] encryptedBytes = null;
string plainText = "";
try
{
// Converting the string message to byte array
//byte[] inputBytes = utf8enc.GetBytes(inputMessage);
// RSAKeyPairGenerator generates the RSA Key pair based on the random number and strength of key required
/*RsaKeyPairGenerator rsaKeyPairGnr = new RsaKeyPairGenerator();
rsaKeyPairGnr.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(new SecureRandom(), 512));
Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair = rsaKeyPairGnr.GenerateKeyPair();
*/
StreamReader sr = File.OpenText(privateKeyFileName);
PemReader pr = new PemReader(sr);
PemReader pemReader = new PemReader(new StringReader(privateKeyFileName));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
Console.WriteLine(keyPair.ToString());
AsymmetricKeyParameter privatekey = keyPair.Private;
Console.WriteLine(pr.ReadPemObject());
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
AsymmetricKeyParameter privateKey = ReadAsymmetricKeyParameter(privateKeyFileName);
// Creating the RSA algorithm object
IAsymmetricBlockCipher cipher = new RsaEngine();
Console.WriteLine("privateKey: " + privateKey.ToString());
// Initializing the RSA object for Decryption with RSA private key. Remember, for decryption, private key is needed
//cipher.Init(false, KeyPair.Private);
//cipher.Init(false, KeyPair.Private);
cipher.Init(false, keyPair.Private);
// Read encrypted text from file
encryptedFile = File.OpenRead(encryptedFileName);
encryptedBytes = new byte[encryptedFile.Length];
encryptedFile.Read(encryptedBytes, 0, (int)encryptedFile.Length);
//Encrypting the input bytes
//byte[] cipheredBytes = cipher.ProcessBlock(inputBytes, 0, inputMessage.Length);
byte[] cipheredBytes = cipher.ProcessBlock(encryptedBytes, 0, encryptedBytes.Length);
//Write the encrypted message to file
// Write encrypted text to file
plainFile = File.CreateText(plainTextFileName);
plainText = Encoding.Unicode.GetString(cipheredBytes);
plainFile.Write(plainText);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception encrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (plainFile != null)
{
plainFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
}
}
// Decrypt a file
static void Decrypt(string privateKeyFileName, string encryptedFileName, string plainFileName)
{
// Variables
CspParameters cspParams = null;
RSACryptoServiceProvider rsaProvider = null;
StreamReader privateKeyFile = null;
FileStream encryptedFile = null;
StreamWriter plainFile = null;
string privateKeyText = "";
string plainText = "";
byte[] encryptedBytes = null;
byte[] plainBytes = null;
try
{
// Select target CSP
cspParams = new CspParameters();
cspParams.ProviderType = 1; // PROV_RSA_FULL
//cspParams.ProviderName; // CSP name
rsaProvider = new RSACryptoServiceProvider(cspParams);
// Read private/public key pair from file
privateKeyFile = File.OpenText(privateKeyFileName);
privateKeyText = privateKeyFile.ReadToEnd();
// Import private/public key pair
rsaProvider.FromXmlString(privateKeyText);
// Read encrypted text from file
encryptedFile = File.OpenRead(encryptedFileName);
encryptedBytes = new byte[encryptedFile.Length];
encryptedFile.Read(encryptedBytes, 0, (int)encryptedFile.Length);
// Decrypt text
plainBytes = rsaProvider.Decrypt(encryptedBytes, false);
// Write decrypted text to file
plainFile = File.CreateText(plainFileName);
plainText = Encoding.Unicode.GetString(plainBytes);
plainFile.Write(plainText);
}
catch (Exception ex)
{
// Any errors? Show them
Console.WriteLine("Exception decrypting file! More info:");
Console.WriteLine(ex.Message);
}
finally
{
// Do some clean up if needed
if (privateKeyFile != null)
{
privateKeyFile.Close();
}
if (encryptedFile != null)
{
encryptedFile.Close();
}
if (plainFile != null)
{
plainFile.Close();
}
}
} // Decrypt
I figured this out. Basically to read a private openssl key using BouncyCastle and C# is like this:
static AsymmetricKeyParameter readPrivateKey(string privateKeyFileName)
{
AsymmetricCipherKeyPair keyPair;
using (var reader = File.OpenText(privateKeyFileName))
keyPair = (AsymmetricCipherKeyPair)new PemReader(reader).ReadObject();
return keyPair.Private;
}
Then this key can be used to decrypt data such as below:
AsymmetricKeyParameter key = readPrivateKey(pemFilename);
RsaEngine e = new RsaEngine();
e.Init(false, key);
byte[] decipheredBytes = e.ProcessBlock(cipheredData, 0, cipheredData.Length);

Create a X509Certificate2 from RSACryptoServiceProvider fails with Cannot find the requested object

Sample code:
CspParameters cspParameters = new CspParameters();
cspParameters.ProviderType = 1; // PROV_RSA_FULL
// Create the crypto service provider, generating a new
// key.
mRsaCSP = new RSACryptoServiceProvider(mDefaultKeyLength, cspParameters);
mRsaCSP.PersistKeyInCsp = true;
RSAParameters privateKey = mRsaCSP.ExportParameters(true);
byte[] rsaBytes = mRsaCSP.ExportCspBlob(true);
try
{
X509Certificate2 cert = new X509Certificate2(rsaBytes);
mKeyDataPfx = Convert.ToBase64String(cert.Export(X509ContentType.Pkcs12, password));
}
catch (Exception ce)
{
string error = ce.Message;
}
Here is my solution, using the BouncyCastle library.
// create the RSA key from an XML string
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
key.FromXmlString(keyTextBox.Text);
// convert to BouncyCastle key object
var keypair = DotNetUtilities.GetRsaKeyPair(key);
var gen = new X509V3CertificateGenerator();
string certName = Path.GetFileNameWithoutExtension(fileName);
var name = new X509Name("CN=" + certName);
var serial = BigInteger.ProbablePrime(120, new Random());
gen.SetSerialNumber(serial);
gen.SetSubjectDN(name);
gen.SetIssuerDN(name);
gen.SetNotAfter(DateTime.Now.AddYears(10));
gen.SetNotBefore(DateTime.Now);
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(keypair.Public);
// generate the certificate
var newCert = gen.Generate(keypair.Private);
// convert back to .NET certificate
var cert = DotNetUtilities.ToX509Certificate(newCert);
// export as byte array
byte[] certData = cert.Export(X509ContentType.Pfx);
File.WriteAllBytes(fileName, certData);

Categories

Resources