Reputation: 61
I am trying to use RSA encryption in JavaScript and then decrypt it in C#. In JavaScript I am using the library jsencrypt. In C# I using the API "bouncy castle". When I do the encryption/decryption within the same language everything works. I get back the correct text when I decrypt it. When I try to decrypt in C# what was encrypted in JavaScript I get nothing close. I am sure the keys are the same between the two. An example of the code is below. Any help on how to solve this would be greatly appreciated.
JavaScript
//using jsencrypt.min.js
var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#input').val());
take the value I get from JavaScript "encrypted" and use it in C# for "encyp"
AsymmetricCipherKeyPair KeyParameterPrivate;
byte[] cipheredBytes = Convert.FromBase64String(encyp);
string privateKeyFileName = @"C:\private.pem";
using (var fileStream2 = File.OpenText(privateKeyFileName))
{
PemReader pemReader2 = new Org.BouncyCastle.OpenSsl.PemReader(fileStream2);
KeyParameterPrivate = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)pemReader2.ReadObject();
}
IAsymmetricBlockCipher cipher2 = new Org.BouncyCastle.Crypto.Engines.RsaEngine();
RsaKeyParameters privateKey2 = (RsaKeyParameters)KeyParameterPrivate.Private;
//cipher.Init(false, publicKey4);
cipher2.Init(false, privateKey2);
byte[] deciphered = cipher2.ProcessBlock(cipheredBytes, 0, cipheredBytes.Length);
string decipheredText = utf8enc.GetString(deciphered);
Upvotes: 6
Views: 2230
Reputation: 2534
My advice is to keep it as simple as possible and not use Bouncy Castle for this. You need to create a public key for encryption, private key for decryption and a certificate to fetch the private key from.
First, create private key and certificate PEM files using OpenSSL:
openssl req -newkey rsa:1024 -nodes -keyout private_key.pem -x509 -days 365 -out certificate.pem
Then create a public key PEM file from the certificate that you created:
openssl x509 -pubkey -noout -in certificate.pem > public_key.pem
Then export a PFX file using the private key and certificate PEM files that you created:
openssl pkcs12 -export -out certificate.pfx -inkey private_key.pem -in certificate.pem
When you do the export, you'll be asked to provide a certificate password.
Now here is how to do the RSA decryption in C#:
var cert = new X509Certificate2(@"C:\path\to\certificate.pfx", "password");
var rsaCng = (RSACng)cert.PrivateKey;
var decryptedText = Encoding.UTF8.GetString(rsaCng.Decrypt(Convert.FromBase64String(encryptedText), RSAEncryptionPadding.Pkcs1));
Upvotes: 2
Reputation: 11
Tell me if it works for you.
public string Decrypt(RSACryptoServiceProvider provider, string toDecrypt)
{
var input = Convert.FromBase64String(toDecrypt);
IEnumerable<byte> output = new List<byte>();
for (var i = 0; i < input.Length; i = i + input.Length)
{
var length = Math.Max(input.Length - i, 128);
var block = new byte[length];
Buffer.BlockCopy(input, i, block, 0, length);
var chunk = provider.Decrypt(block, false);
output = output.Concat(chunk);
}
return Encoding.UTF8.GetString(output.ToArray());
}
Upvotes: 0
Reputation: 93948
You'll have to use new PKCS1Encoding(cipher2)
. The RSAEngine
only produces plain (also known as raw or textbook) RSA.
Upvotes: 0
Reputation: 9499
Why would you want to torture yourself using BC for this?
The easiest approach to decryption here is :
// store is a X509Store pointing to the correct store on the target machine
// You have to ensure that the security principal for your app has access to the private key to decrypt
X509Certificate2 cert = store.Certificates.Find(X509FindType.FindByThumbprint, "sha1hash", false)[0];
var prov = (RSACryptoServiceProvider)cert.PrivateKey;
var decipheredText = Encoding.UTF8.GetString(prov.Decrypt(Convert.FromBase64String(target), false));
Obviously you can get your X509Certificate2 from file or any other means, e.g. X509Certificate2 cert = new X509Certificate2(@"C:\someCert.pfx", "somePass");
If you followed jsencrypt tutorial, use this openssl command to get the pfx out of the pems you have:
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.pem -in publicKey.pem
Upvotes: 0