Decrypt passphrase protected PEM containing private key - c#

I have the following method that creates an Encrypted Private Key using Bouncy Castle for C#:
public string GetPrivateKey(AsymmetricCipherKeyPair keyPair, string password)
{
var generator = new Pkcs8Generator(keyPair.Private, Pkcs8Generator.PbeSha1_3DES);
generator.IterationCount = 4;
generator.Password = password.ToCharArray();
var pem = generator.Generate();
TextWriter textWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(pem);
pemWriter.Writer.Flush();
string privateKey = textWriter.ToString();
return privateKey;
}
Which looks like this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
...
-----END ENCRYPTED PRIVATE KEY-----
What I don't know is how to consume the password used to encrypt the private key in my Decrypt method. Right now, without knowing how to "decrypt" my private key using he password, I get the following Exception:
Org.BouncyCastle.OpenSsl.PemException : problem creating ENCRYPTED
private key: System.NullReferenceException: Object reference not set
to an instance of an object. at
Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)
Here is the code for the Decrypt method:
public string Decrypt(string base64Input, string privateKey, string password)
{
var bytesToDecrypt = Convert.FromBase64String(base64Input);
//get a stream from the string
AsymmetricCipherKeyPair keyPair;
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(privateKey))
{
var obj = new PemReader(txtreader).ReadObject();
keyPair = (AsymmetricCipherKeyPair) obj;
decryptEngine.Init(false, keyPair.Private);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}

It seems to me that you need to decrypt the private key to use it. Currently your password parameter isn't used. Unfortunately it doesn't seem to be all that easy to find out how do this.
Bouncy Castle, as many other Java API's, use a password handler to retrieve the password. The reason to do this is to allow the program to ask the user for the password only when it is required. This allows the program to leave the password in memory for the shortest amount of time.
So to allow for decryption, use the following constructor:
PemReader(TextReader reader, IPasswordFinder pFinder);
with an implementation of IPasswordFinder (Bouncy Castle for C# is mainly a Java port, otherwise a delegate would probably have been used).
For your convenience, the code. This code also reconstructs the entire key pair, not just the private key.
Import statements:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.IO;
the decoder:
private static AsymmetricCipherKeyPair DecodePrivateKey(string encryptedPrivateKey, string password)
{
TextReader textReader = new StringReader(encryptedPrivateKey);
PemReader pemReader = new PemReader(textReader, new PasswordFinder(password));
object privateKeyObject = pemReader.ReadObject();
RsaPrivateCrtKeyParameters rsaPrivatekey = (RsaPrivateCrtKeyParameters)privateKeyObject;
RsaKeyParameters rsaPublicKey = new RsaKeyParameters(false, rsaPrivatekey.Modulus, rsaPrivatekey.PublicExponent);
AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(rsaPublicKey, rsaPrivatekey);
return kp;
}
required helper class:
private class PasswordFinder : IPasswordFinder
{
private string password;
public PasswordFinder(string password)
{
this.password = password;
}
public char[] GetPassword()
{
return password.ToCharArray();
}
}
Note that normally you should only use char[] instead of string for passwords as char[] can be cleared after use, while string cannot.
Now you have the private key decryption should be easy.

Related

Bouncy Castle Encrypt and Decrypt Password - Org.BouncyCastle.Crypto.InvalidCipherTextException: 'block incorrect'

NOTE: This is NOT for encrypting user passwords. Use a Hash to store user passwords. You can also throw some salt on those passwords similarly to salt bae.
I need to store one of my passwords to log into a program. I can encrypt the password but when I decrypt I get the error:
Org.BouncyCastle.Crypto.InvalidCipherTextException: 'block incorrect'
I am going to use a different private key so I'm not worried about posting this one here.
Program Class:
var input = "TestPassword123!";
Encryption EC = new Encryption();
var Key = "-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQCr874y+f3cYtz8hOuxamwHYUK7WS03c3t7LHMuCpmiR9wOz1FHEbBk6ZdvhY74I9sE+lIs0bUZVh08nKIS/txeECZ/d3WYDm8gW+mFjg0xD7LgQ9Prchsvrb2Q9c6FK5Us8i0iqOhDmrZdCYO+/zhyrYnP/Wy1EZTWPvMrI/GVWwIDAQABAoGBAJW5Sg8HIKYKq5NxhezY1rHiXYHWV4nmE0ogXTZk4nusiI+Ys5PncimcQFFKAUBNsEL4WB9QhplGI3UIihNyOZx68waSB6NiAi+tz8i7edTxDfwWkM271roOJxD3RzUJuQkyc57ZxrD61UyodRatmRoJkPhLBlEvIr9/dCwYBl0pAkEA5ucK8CFdxr4DWIAutZLeeeQx9oe1tCi/iUvEpSDOHKAvaELLBiD4bIInN4nx/Gj1gwHqICg8L/gs0x23cQWz3QJBAL6kYaRQFvCmVajTaTJ3ef3gYwynPsmfT5Urx0DWW5rXtbtZQ7vScDKRU4YbmBb3tD5eT/Fl/dIakPGv+hxllpcCQA3o5TPKDsgmMjVmo2m0y0o0gP4E9uE/gypWMiZwb3ox/CkfvPNFkTGYNZyW5sj52bBmsR/2zIlnPewJ4j8gxNECQDOT/8LX1E0Jg5VolUaNIpk4UzQCL6+XBY4DSSZWmHQdNlLYxMWVGrvjq6hV4OEd5UsWcySJhpGIlHx/Mvjp10MCQAon0SLhRI8QNrWfp/dLuFdqTy4b4y64j3HvooOu6GDZwCLwjqvwML3rimxUi52EQspssIOlLjpQjvIJvYBKBys=-----END RSA PRIVATE KEY-----";
var encrypted = EC.RsaEncrypt(input, Key);
string password = EC.RsaDecrypt(encrypted, Key);
Encryption Class
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.OpenSsl;
namespace TemarkNamespace
{
internal class Encryption
{
public string RsaEncrypt(string clearText, string Key)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(Key))
{
var keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
encryptEngine.Init(true, keyPair.Private);
}
var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
return encrypted;
}
// Decryption:
public string RsaDecrypt(string pass, string Key)
{
var bytesToDecrypt = Convert.FromBase64String(pass);
AsymmetricCipherKeyPair keyPair;
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(Key))
{
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
decryptEngine.Init(false, keyPair.Private);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}
}
}
I found this code and it seems to work fine
using System.Security.Cryptography;
public string Encrypt(string s)
{
if (String.IsNullOrEmpty(s))
{
return s;
}
else
{
var encoding = new UTF8Encoding();
byte[] plain = encoding.GetBytes(s);
byte[] secret = ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(secret);
}
}
public string Decrypt(string s)
{
if (String.IsNullOrEmpty(s))
{
return s;
}
else
{
byte[] secret = Convert.FromBase64String(s);
byte[] plain = ProtectedData.Unprotect(secret, null, DataProtectionScope.CurrentUser);
var encoding = new UTF8Encoding();
return encoding.GetString(plain);
}
}

Trying to decrypt a string with public key(not private) using bouncycastle in .net

As a sample app, I encrypted a string using an rsa public key(supplied by a 3rd party api) using BouncyCastle library in .NET. When I send this encrypted string to the said 3rd party api endpoint, it is able to decrypt it(using its private key). I don't have their private key, but, is it possible to decrypt the string on my end using just the public key that I have?
From my understanding of RSA public/private key pair, when decrypting, you use the private key stored with you to decrypt a string and use the public key to confirm that you are receiving data from a said source.
public string RsaEncryptWithPublic(string clearText
, string publicKey)
{
var bytesToEncrypt = Encoding.UTF8.GetBytes(clearText);
var encryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(publicKey))
{
var keyParameter = (AsymmetricKeyParameter)new PemReader(txtreader).ReadObject();
encryptEngine.Init(true, keyParameter);
}
var encrypted = Convert.ToBase64String(encryptEngine.ProcessBlock(bytesToEncrypt, 0, bytesToEncrypt.Length));
return encrypted;
}
public string RsaDecrypt(string base64Input
, string privateKey)
{
var bytesToDecrypt = Convert.FromBase64String(base64Input);
//get a stream from the string
AsymmetricCipherKeyPair keyPair;
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(privateKey))
{
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
//decryptEngine.Init(false, keyPair.Private);
decryptEngine.Init(false, keyPair.Public);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}
static void Main(string[] args)
{
string _creditCardNumber = "5454545454545454";
string publicKey = System.IO.File.ReadAllText(#"C:\ThirdPartyKeys\RSAPublicKey_01.txt");
var enc = new EncryptionClass();
var encryptedWithPublic = enc.RsaEncryptWithPublic(_creditCardNumber, publicKey);
Console.WriteLine("String: " + _creditCardNumber);
Console.WriteLine("Encrypted String: " + encryptedWithPublic);
// Decrypt
var outputWithPublic = enc.RsaDecrypt(encryptedWithPublic, publicKey);
//var outputWithPrivate = enc.RsaDecrypt(encryptedWithPrivate, _privateKey);
Console.WriteLine("Decrypted String: " + outputWithPublic);
}
The encryption works, but when I try to decrypt with the same public key, it complains of
Invalid Cast Exception:
Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'.
at line in RsaDecrypt function:
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
No. It's Asymmetric Encryption which means you can't decrypt it with the public key. If you could, it would defeat the purpose and anyone with the public key would be able to decrypt your secret message

rsacryptoserviceprovider.VerifyData always returns false

Below is my C# Program that verifies a response from a php script which is using phpseclib
static void Main(string[] args)
{
var payment =
"VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ=";
var signature =
"V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk=";
var sigByte = Convert.FromBase64String(signature);
var payBite = Convert.FromBase64String(payment);
Verify(payBite, sigByte);
}
public static bool Verify(byte[] payment, byte[] signature)
{
var key = Resources.PublicKey;
var cipher = Crypto.DecodeX509PublicKey(key);
var res = cipher.VerifyData(payment, "SHA256", signature);
return res;
}
the public key used is below:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ
/GQFct8GoUevNELG7wIDAQAB
-----END PUBLIC KEY-----
but the verify method seems to be returning false all the time. any idea why this happens.
the same content works in the php code which the vendor gave to me
<?php
//load RSA library
include 'Crypt/RSA.php';
//initialize RSA
$rsa = new Crypt_RSA();
//decode & get POST parameters
$payment = base64_decode("VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ=");
$signature = base64_decode("V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk=");
//load public key for signature matching
$publickey = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ
/GQFct8GoUevNELG7wIDAQAB
-----END PUBLIC KEY-----";
$rsa->loadKey($publickey);
//verify signature
$signature_status = $rsa->verify($payment, $signature);
//get payment response in segments
//payment format: order_id|order_refference_number|date_time_transaction|payment_gateway_used|status_code|comment;
$responseVariables = explode('|', $payment);
//display values
echo $signature_status;
echo '<br/>';
var_dump($responseVariables);
?>
Any idea what i'm doing wrong here. i tried passing "SHA512", "MD5" all in the C# code and still returns false.
PSS is supported in-the-box with .NET 4.6+, but requires using the RSACng class (CAPI, which RSACryptoServiceProvider is based on, doesn't offer it).
public static bool Verify(byte[] payment, byte[] signature)
{
var key = Resources.PublicKey;
// Change the function this calls to return RSACng instead of RSACryptoServiceProvider.
RSA cipher = Crypto.DecodeX509PublicKey(key);
// or, failing being able to change it:
RSA tmp = new RSACng();
tmp.ImportParameters(cipher.ExportParameters(false));
cipher = tmp;
return cipher.VerifyData(
payment,
signature,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pss);
}
Well, seems like the vendor is NOT using PKCS1, he's using PSS. Verify it this way (requires Bouncy Castle!):
public static bool Verify(byte[] payment, byte[] signature)
{
var pub = #"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYYf/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ/GQFct8GoUevNELG7wIDAQAB";
byte[] raw = Convert.FromBase64String(pub);
AsymmetricKeyParameter aKey = PublicKeyFactory.CreateKey(raw);
RsaKeyParameters rKey = (RsaKeyParameters)aKey;
PssSigner pss = new PssSigner(new RsaEngine(), new Sha1Digest(), 20);
pss.Init(false, rKey);
pss.BlockUpdate(payment, 0, payment.Length);
var res = pss.VerifySignature(signature);
return res;
}

How to unwrap a key using RSA in Bouncy castle c#?

How do I unwrap a key using RSA private key in Bouncy castle? I receive the already wrapped key which was wrapped using the RSA public key. I have the RSA key pair. I just cannot find the api in the C# Bouncy Castle that I can use to unwrap it.
This code in the C# source code (https://github.com/bcgit/bc-csharp) is currently commented out. The commented out lines for the RSA is exactly what I need, but when I try to use them it seems that its been removed or never implemented
Key key = cipher.unwrap(wrappedKey, "RSA", IBufferedCipher.PRIVATE_KEY);
The line above is exactly what I need. Why has it been commented out? The full function in WrapTest.cs is given below:
public ITestResult Perform()
{
try
{
// IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/PKCS5Padding");
IWrapper cipher = WrapperUtilities.GetWrapper("DES/ECB/PKCS5Padding");
IAsymmetricCipherKeyPairGenerator fact = GeneratorUtilities.GetKeyPairGenerator("RSA");
fact.Init(
new RsaKeyGenerationParameters(
BigInteger.ValueOf(0x10001),
new SecureRandom(),
512,
25));
AsymmetricCipherKeyPair keyPair = fact.GenerateKeyPair();
AsymmetricKeyParameter priKey = keyPair.Private;
AsymmetricKeyParameter pubKey = keyPair.Public;
byte[] priKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(priKey).GetDerEncoded();
CipherKeyGenerator keyGen = GeneratorUtilities.GetKeyGenerator("DES");
// Key wrapKey = keyGen.generateKey();
byte[] wrapKeyBytes = keyGen.GenerateKey();
KeyParameter wrapKey = new DesParameters(wrapKeyBytes);
// cipher.Init(IBufferedCipher.WRAP_MODE, wrapKey);
cipher.Init(true, wrapKey);
// byte[] wrappedKey = cipher.Wrap(priKey);
byte[] wrappedKey = cipher.Wrap(priKeyBytes, 0, priKeyBytes.Length);
// cipher.Init(IBufferedCipher.UNWRAP_MODE, wrapKey);
cipher.Init(false, wrapKey);
// Key key = cipher.unwrap(wrappedKey, "RSA", IBufferedCipher.PRIVATE_KEY);
byte[] unwrapped = cipher.Unwrap(wrappedKey, 0, wrappedKey.Length);
//if (!Arrays.AreEqual(priKey.getEncoded(), key.getEncoded()))
if (!Arrays.AreEqual(priKeyBytes, unwrapped))
{
return new SimpleTestResult(false, "Unwrapped key does not match");
}
return new SimpleTestResult(true, Name + ": Okay");
}
catch (Exception e)
{
return new SimpleTestResult(false, Name + ": exception - " + e.ToString());
}
}
I'm not entirely clear on what you need, but you can use RSA keys to wrap and unwrap AES keys in Bouncycastle. Here is a Java example that creates an RSA keypair, saves the private key to a file, and then saves an AES key that has been wrapped in the public key.
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
public class Main {
private static final SecureRandom rand = new SecureRandom();
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024, rand);
KeyPair kp = kpg.generateKeyPair();
// Write out private key to file, PKCS8-encoded DER
Files.write(Paths.get("privkey.der"), kp.getPrivate().getEncoded());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256, rand);
SecretKey aesKey = kg.generateKey();
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
c.init(Cipher.WRAP_MODE, kp.getPublic(), rand);
byte[] wrappedKey = c.wrap(aesKey);
// Write out wrapped key
Files.write(Paths.get("wrappedkey"), wrappedKey);
}
}
And here is a C# example that consumes the output from the Java example and unwraps the AES key.
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace RSADecryptWithBouncy
{
class MainClass
{
private static KeyParameter Unwrap(byte [] key, AsymmetricKeyParameter privKeyParam) {
var wrapper = WrapperUtilities.GetWrapper("RSA/NONE/PKCS1PADDING");
wrapper.Init(false, privKeyParam);
var aesKeyBytes = wrapper.Unwrap(key, 0, key.Length);
return new KeyParameter(aesKeyBytes);
}
public static void Main(string[] args)
{
var privKeyBytes = File.ReadAllBytes("../../privkey.der");
var seq = Asn1Sequence.GetInstance(privKeyBytes);
var rsaKeyParams = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq));
var wrappedKey = File.ReadAllBytes("../../wrappedKey");
var aesKey2 = Unwrap(wrappedKey, rsaKeyParams);
}
}
}
You will have to adapt this to your needs.

C# RSA Decrypt Using Private Key

I've been searching but I can't seem to find a simple way of decrypting using RSA.
I have generated a public and private key, they are stored in two separate files and are in the XML format. I have no problem associating the public key to the RSACryptoServiceProvider object using FromXmlString, and then encrypting a string. My confusion comes when trying to decrypt an encrypted string. I'm not sure how I associate the private key data with the RSACryptoServiceProvider so that I can use the Decrypt function.
Any help would be appreciated.
EDIT:
The format of the public and private key is XML generated by the RSACryptoServiceProvider object, which I just put into a file:
<RSAKeyValue><Modulus>vS7Y5up+6kHMx7hQjKA6sKlIVASaw ... etc ...
I load the public key using this code:
StreamReader sr = new StreamReader(HttpContext.Current.Server.MapPath("public.key"));
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(sr.ReadToEnd().ToString());
I currently haven't tried anything with the private key yet, since I'm not sure where to start.
I don't know your situation but I would suggest that you store you key information in a KeyContainer. If you do this you can access the keyContainer by name and can do something like this.
// retrieves the maximum number of characters that can be decrypted at once
private int getMaxBlockSize(int keySize){
int max = ((int)(keysize/8/3) )* 4
if (keySize / 8 mod 3 != 0){
max += 4
}
return max;
}
public string decrypt(string msg, string containerName){
CspParameters params = new CspParameters();
params.KeyContainerName = containerName;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(params);
StringBuilder decryptedMsg = new StringBuilder();
int maxDecryptSize = getMaxBlockSize(rsa.KeySize);
int iterationCount = Math.Floor(msg.length / maxDecryptSize)
for(int i=0; i<iterationCount; i++){
int start = i * maxDecryptSize;
int blkSize = Math.min(start + maxDecryptSize, msg.Length);
Byte[] msgBytes = System.Convert.FromBase64String(msg.Substring(start, blkSize));
decryptedMsg.Append(System.Text.Encoding.Unicode.GetString(RSAProvider.Decrypt(msgBytes, false));
}
return decryptedMsg.ToString();
}
I haven't tested this out so there might be a bug in here but the you get the idea.
if you have private key in text format
like given below
-----BEGIN RSA PRIVATE KEY-----
text....
-----END RSA PRIVATE KEY-----
public string RsaDecryptWithPrivate(string base64Input, string privateKey)
{
var bytesToDecrypt = Convert.FromBase64String(base64Input);
AsymmetricCipherKeyPair keyPair;
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(privateKey))
{
keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();//fetch key pair from text file
decryptEngine.Init(false, keyPair.Private);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}

Categories

Resources