C# create ssh-rsa public key from existing private key string - c#

I wish to create an ssh-rsa public key from an existing private key string
for example:
for the following private rsa key string:
-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAvyN0aQKoYl/LAZ/1dQt0rWuSNyOty88k3439HT3rcT/vhaSk d5lbnNKiYTzdDEkAxAnx4rxw6bEdD/8A9ISs0jy3pFRORFdbgBVFjIPR2NKbwVbs 9fcQNOQHcNslAyHA/yy57ktw+/6VyHYnHfXFlhkt1Jx4A1ubFIGzXttnXkwuNhdn 2JLJ5+JA3zRDJNBZR7p7NHVu9cRBwADm/WSzPqI6Sgs8kkU0eBcfy7qJRao3cmR5 95lLxkhFARufSW8lD/tCs2k99T2ZwZpKJpliA5VGjIC3iHhck3tpXs5w9sQ5Axhv n1kTq5GKNi48r132KgRNJO+jIY0QSI60A6akbwIDAQABAoIBACCB3SiG5TBl7lbG Z66SVjOwWdu627IP9st2kJfKkiJep1PpXndgw632PNugyE9wkwrETjkrp2B3WOQB kJ4Feob/AJSYKf+Bg/RSqdNuD+B6YTcOm5pxfHYiWgmdm7ven75GUxDuD7cr4zmG rrxvsj0G5z6Dpf2cNNHWBTWaxwfITaC8yXp6dx8o8V86/T0qrsEl+S0YJ5VQWt6L I5GzipFNhhjcaemkOxDJg2T/g0FbpBEuj3RnwWNfRiiTCt+AuROg6/4M2oyLBE9W e8n8KAUhZvRJA2dFwzZY38U9MfX9k9zIkJXtpkeghGx3M2zG3cQcFOaly6aFNHjr QuEd6kECgYEA7NQgfqxuJ34kMnmtZeYccFGI6WUosuXUlgMhqU8CUnjIaRX8u8Ho UjvjbezHNsI8tyH3vopgHNqTkcuElyuxKZQBTtUOFGG4a1HUS5tlo913DcnuSVIa qL8kn3XVDHvuTr8tJbsb4KXrEMFfGoJBemU4ixSDiYWk/FdXvyyEEbECgYEAzpx6 JPOktmdaLf8U7snvlRY9daBqKfPqtKDxYgsC3xOp90Z3FMWQi5OyPmBsLGmjHxhe YrPYQ3lbRh2JuRgZ7rTAxXN9dnDNgrh4tFjEEqQiFBCGlhP6syNM9Kx0YYNAoJN4 U29Tv71rxHJiFaLiRTh3Nopdn5ir4Raoj2fQgB8CgYBxCCFmNAfzA2plSNuwia5D ETcmJejR0Y2v91imhRYXpJwKQ7s3JaorLXgzq9G82eG+ihDDOSn8O3o5GIh02h6Z OJGTPW6V3bn2RrzrRQSyu+2pgBohlnUw2uGw1b1UUwX/QZFbs7zvcGELwy8P6OE1 eIAPKUBKb6W55jnz/VwfUQKBgGPTpQyPkAj1vNO2iLWrag/dtApOXJ0yljd5/8cA TP3dsWShbk3h+yoFTbznt7xpuf//NTN5c8d+LkSdZvrAk18LhIyidX8xl4pOeTui G/JpzXFmXrDKrHm7V6ZsYLrwwNwVBLFDe/KLojNDlPKhRbRuSONYTU4cZQeXfA/1 9/6/AoGAarF4JSdpzMzfacpLy2nsOM6XmL76B218uKANSHQy9k1X/Hp1u1StY8tQ H4+DSrRUQBb4sdxkCRXVvMH3zttDGoIrSUvDqN3k4opcP8nmzMc/EDwD3xFgri/p yBXBhE99r1B0p7fneXt58tTqtcevk5dQPzyF9SdsfUxD5PrnZRI= -----END RSA PRIVATE KEY-----
I wish to get the following output:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/I3RpAqhiX8sBn/V1C3Sta5I3I63LzyTfjf0dPetxP++FpKR3mVuc0qJhPN0MSQDECfHivHDpsR0P/wD0hKzSPLekVE5EV1uAFUWMg9HY0pvBVuz19xA05Adw2yUDIcD/LLnuS3D7/pXIdicd9cWWGS3UnHgDW5sUgbNe22deTC42F2fYksnn4kDfNEMk0FlHuns0dW71xEHAAOb9ZLM+ojpKCzySRTR4Fx/LuolFqjdyZHn3mUvGSEUBG59JbyUP+0KzaT31PZnBmkommWIDlUaMgLeIeFyTe2leznD2xDkDGG+fWROrkYo2LjyvXfYqBE0k76MhjRBIjrQDpqRv administrator#LovelyTrust
I tried few ways but unfortunately nothing gave me the desired output, for example, I was able to generate RSA object from my private key using:
public static string ExtractPublicKeyFromPrivate(string privateKey)
{
var rsa = RSA.Create();
rsa.ImportFromPem(privateKey.ToCharArray());
return ""
}
but both
rsa.ExportRSAPublicKey()
rsa.ExportSubjectPublicKeyInfo()
didn't give me the desired output, any ideas?

SSH key format is a bit complex. Moreover, .NET doesn't have a method to directly get the key in this format. However, something like this will work (I tried in a .NET 6 console application, and got the public key exactly how you want it.):
// See https://aka.ms/new-console-template for more information
using System.Security.Cryptography;
using System.Text;
static byte[] ToBytes(int i)
{
byte[] bytes = BitConverter.GetBytes(i);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
return bytes;
}
string privateKey = "-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAvyN0aQKoYl/LAZ/1dQt0rWuSNyOty88k3439HT3rcT/vhaSk d5lbnNKiYTzdDEkAxAnx4rxw6bEdD/8A9ISs0jy3pFRORFdbgBVFjIPR2NKbwVbs 9fcQNOQHcNslAyHA/yy57ktw+/6VyHYnHfXFlhkt1Jx4A1ubFIGzXttnXkwuNhdn 2JLJ5+JA3zRDJNBZR7p7NHVu9cRBwADm/WSzPqI6Sgs8kkU0eBcfy7qJRao3cmR5 95lLxkhFARufSW8lD/tCs2k99T2ZwZpKJpliA5VGjIC3iHhck3tpXs5w9sQ5Axhv n1kTq5GKNi48r132KgRNJO+jIY0QSI60A6akbwIDAQABAoIBACCB3SiG5TBl7lbG Z66SVjOwWdu627IP9st2kJfKkiJep1PpXndgw632PNugyE9wkwrETjkrp2B3WOQB kJ4Feob/AJSYKf+Bg/RSqdNuD+B6YTcOm5pxfHYiWgmdm7ven75GUxDuD7cr4zmG rrxvsj0G5z6Dpf2cNNHWBTWaxwfITaC8yXp6dx8o8V86/T0qrsEl+S0YJ5VQWt6L I5GzipFNhhjcaemkOxDJg2T/g0FbpBEuj3RnwWNfRiiTCt+AuROg6/4M2oyLBE9W e8n8KAUhZvRJA2dFwzZY38U9MfX9k9zIkJXtpkeghGx3M2zG3cQcFOaly6aFNHjr QuEd6kECgYEA7NQgfqxuJ34kMnmtZeYccFGI6WUosuXUlgMhqU8CUnjIaRX8u8Ho UjvjbezHNsI8tyH3vopgHNqTkcuElyuxKZQBTtUOFGG4a1HUS5tlo913DcnuSVIa qL8kn3XVDHvuTr8tJbsb4KXrEMFfGoJBemU4ixSDiYWk/FdXvyyEEbECgYEAzpx6 JPOktmdaLf8U7snvlRY9daBqKfPqtKDxYgsC3xOp90Z3FMWQi5OyPmBsLGmjHxhe YrPYQ3lbRh2JuRgZ7rTAxXN9dnDNgrh4tFjEEqQiFBCGlhP6syNM9Kx0YYNAoJN4 U29Tv71rxHJiFaLiRTh3Nopdn5ir4Raoj2fQgB8CgYBxCCFmNAfzA2plSNuwia5D ETcmJejR0Y2v91imhRYXpJwKQ7s3JaorLXgzq9G82eG+ihDDOSn8O3o5GIh02h6Z OJGTPW6V3bn2RrzrRQSyu+2pgBohlnUw2uGw1b1UUwX/QZFbs7zvcGELwy8P6OE1 eIAPKUBKb6W55jnz/VwfUQKBgGPTpQyPkAj1vNO2iLWrag/dtApOXJ0yljd5/8cA TP3dsWShbk3h+yoFTbznt7xpuf//NTN5c8d+LkSdZvrAk18LhIyidX8xl4pOeTui G/JpzXFmXrDKrHm7V6ZsYLrwwNwVBLFDe/KLojNDlPKhRbRuSONYTU4cZQeXfA/1 9/6/AoGAarF4JSdpzMzfacpLy2nsOM6XmL76B218uKANSHQy9k1X/Hp1u1StY8tQ H4+DSrRUQBb4sdxkCRXVvMH3zttDGoIrSUvDqN3k4opcP8nmzMc/EDwD3xFgri/p yBXBhE99r1B0p7fneXt58tTqtcevk5dQPzyF9SdsfUxD5PrnZRI= -----END RSA PRIVATE KEY-----";
var rsa = RSA.Create();
rsa.ImportFromPem(privateKey.ToCharArray());
byte[] sshrsaBytes = Encoding.Default.GetBytes("ssh-rsa");
byte[] n = rsa.ExportParameters(false).Modulus;
byte[] e = rsa.ExportParameters(false).Exponent;
string buffer64;
using (var ms = new MemoryStream())
{
ms.Write(ToBytes(sshrsaBytes.Length), 0, 4);
ms.Write(sshrsaBytes, 0, sshrsaBytes.Length);
ms.Write(ToBytes(e.Length), 0, 4);
ms.Write(e, 0, e.Length);
ms.Write(ToBytes(n.Length + 1), 0, 4);
ms.Write(new byte[] { 0 }, 0, 1);
ms.Write(n, 0, n.Length);
ms.Flush();
buffer64 = Convert.ToBase64String(ms.ToArray());
}
string comment = "administrator#LovelyTrust";
string publicKey = $"ssh-rsa {buffer64} {comment}";
Console.WriteLine(publicKey);
ToBytes method is simply checks your machine's endianness and converts bytes into correct order if necessary.
We first create an RSA object and import the private key, just like you did. After that, the complex part I mentioned starts, and continues until the end of the using block. Finally, we concatenate that value with ssh-rsa word from the left and the comment (this is the value entered in Key comment text field if you use PuTTY Key Generator) from the right.
This code is heavily inspired from the code of SshKeyGenerator library. Unfortunately, the library itself does not support key import. On the other hand, if you want randomly generated SSH private and public key pairs, using directly the library will be probably easier and more convenient.

Related

.NET Core 3.1 - RSA.ImportRSAPrivateKey raises a CryptographicException

I'm training to asymmetric encryption with RSA. I created a key pair with ssh-keygen, and I managed to encrypt some data with my public key.
But when I try to decrypt this data with my private key, this exception is raised :
System.Security.Cryptography.CryptographicException : 'ASN1 corrupted data.'
Here is my PEM file containing my private key :
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,E79376C1ECFD82F05A871D9245BFC958
iEL9aNdWIC3TckveRH2ADdHrnCAQeyg0GUFx0obx1sHOCDdiCIb2u46vFUQ8QP6H
vHHgA9Kf4lY8Jq6Qkv/Iyhh9WcWTR2nNjbN7Ndlb343MyjeNdlXdVrHsfR8Q98ul
06FiKZdnS640PzxAUvibbmkLVus8g3V14qZqeDTqN1rbOCAk2Kxfy5V4kd6M7wCm
fqABkYpp+2EYf4Z4YcJbLDXEEIg7HD/AI1gPpE5nRQoSib/9bm87j98VnG5dOYAJ
38ZMTvJjIImQveOUeSNyR/re71V+YUy0N/zvqMrlp4pDFsDb6infZga0jPFzGXGy
5S3XYXSs9iPReFHQnhWr/L3dRx9TpfZJcl4BJ6D8j9wxrWRcharGNNgCK/kV9FJw
BpwFu01jNESDHV3dyWTcOAzQit4pDkr0A9EK4N1vfWaLLO8vqyGtqlvtU5sD2rYQ
JvrMEsUsAYXJcBDUX2cksNEen+7s338cBGg4NdE+xAUeKv5EysYIKgojPJi6WQ39
FAgkr1TfWaffO/TgfL/DwC1wyHXleNyDQ87unyxRIRu/wWnqJaQQG8Z0BilIbDp8
KrKfkHW9CWaPCbldOzHJ5UDZmA5+AvfoaATRw/vW1Wg0GYkuNqqHzV7tNFKcnUG1
DmIaSI+Y55cngqeOStFfgRTehbXK84w3PzR3lnpuxG4rtOjDV8RfZSozaSValqju
ZWRYEbKn7Za2XZWJT4kkDa5O4nJUMbihBOUL+FWc6dmDIaZY/nUKJAm2pxmd0R1s
9PcXhqLEnBTvGh1CrOdhiqkHQ5A5OtIp/FrPhUltjsy129NC5/dPZaN9v4TgNYQu
zNd8vSlVXuimB+2OoXu3fNE75ywxmrs4H8M4y3u87GQWFdYwQFFnv2fyCzV8iqvy
ybQR599v5qL2IKvHdw68q9PDmasd4jSTAoFP/g6QQKMCaQuMUbrtlHzvPvNnCgk1
AChbFeuLK57c2rwVwTx0YEATcKz27/V5af0E2x6sLDoqQv5SBkREuuWyA6DsSO/S
vX1WR/hZWk2PVi24N/AG8T/sIfyBeTPw7Yx3RuT5MWLdR6haSEKkGGrGuxr1HnoF
lt3JruZczavGpAn5Q8DSVKb78Q8kqI/gdLYNIuq5Yy7Mz1ldocN0N2CarUGWgU7e
+z0TM2CWkTBE7Q0CU4Na5QusvaLYDgH4LW4WY9BNN86C4uKQFjJHz6gZoI3zx8/L
RxN2bGyd0H83k4xuQXml2RnnPPB6L5JwJxxme5ecWpMdp5c6xyXX1ZPKkkGuRbFs
OxeQqNNfPEExqtC2U/Jn5B1HYJqCYCeKlUNdqUoZv5vT8x9UDoE5vKtP3DtTckeB
+6n7S2viNWzV2qid8moh9DfWGMlF4i1y91pdcNJx+M01OfLOB1EPlD0MoTvkfU6s
x0VQh5t4wCbcJ7kcIrp2siPbBg4RPV8MNKtaBhTvFf+nH1TAEsUMjdi7FrnfBn3b
4o4BqC+ibQHC/+SkGAxRakdJjM5XcXO1BZp4zLYSBQyXGu7kp8ohOvHx65vtwvls
XCdbtnJs/iAORxAgLnuVPzLUfTd6bLlszOsyIvC8+j587GX5YFW+h4s+bicZMwCm
-----END RSA PRIVATE KEY-----
And here is the code sample using this private key :
static string RSA_Decrypt(byte[] value)
{
byte[] deciphered;
using (var reader = File.OpenText(#"C:\Users\???\.ssh\id_rsa"))
{
// Extracting the payload
string privateKeyFile = reader.ReadToEnd();
var exp = privateKeyFile.Split("\n\n");
var privateKey = exp[1].Split("\n-----")[0];
// using the payload to decrypt my data
using(var rsa = RSA.Create())
{
rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _); //CryptographicException
deciphered = rsa.Decrypt(value, RSAEncryptionPadding.Pkcs1);
}
}
return Encoding.Default.GetString(deciphered);
}
What am I doing wrong?
The posted private key is a PEM encoded PKCS#1 key that is encrypted.
RSA.ImportRSAPrivateKey() can only import unencrypted keys of this format that are furthermore DER encoded. The DER encoding results from the PEM encoding by removing the header and footer and Base64 decoding the rest.
As far as I know, an encrypted PKCS#1 key cannot be imported with .NET Core 3.1 on-board means. But an import is possible with BouncyCastle and its Org.BouncyCastle.OpenSsl.PemReader class, see e.g. here.
Unlike the PKCS#1 format, a DER encoded private key in PKCS#8 format can be imported with .NET Core 3.1 out of the box (RSA.ImportPkcs8PrivateKey()), even if it is encrypted (RSA.ImportEncryptedPkcs8PrivateKey()).
Keys of this format can be generated e.g. with openssl genpkey. With OpenSSL it is also possible to convert between the formats.
Thanks Topaco, that's exactly what I needed! I used BouncyCastle to decrypt my private key, and now it's working perfectly! I don't know why RSA class does not have any method to do it...
So here is my code now :
static string RSA_Decrypt(byte[] value)
{
string deciphered;
using (var reader = File.OpenText(#"C:\Users\???\.ssh\id_rsa"))
{
string privateKeyFile = reader.ReadToEnd();
var keyReader = new StringReader(privateKeyFile);
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
object pemReader = new PemReader(keyReader, new PasswordFinder("azerty")).ReadObject();
var keyPair = (AsymmetricCipherKeyPair)pemReader;
decryptEngine.Init(false, keyPair.Private);
deciphered = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(value, 0, value.Length));
}
return deciphered;
}
PS : Yeah, my private key password is "azerty" ^^ I wasn't inspired when I created my key pair ^^

Asymetric encryption algorithm which allows to use public and private key for both encryption and decryption

I have the following working asymetric encryption implementation:
private static RSAParameters privateKey;
private static RSAParameters publicKey;
private static void RSA()
{
var rsa = new RSACryptoServiceProvider();
privateKey = rsa.ExportParameters(true);
publicKey = rsa.ExportParameters(false);
byte[] originalMessage = GenerateRandomData();
byte[] encryptedMessage = Using(publicKey).Encrypt(originalMessage, false);
byte[] decryptedMessage = Using(privateKey).Decrypt(encryptedMessage, false);
Debug.Assert(originalMessage.SequenceEqual(decryptedMessage));
}
private static RSACryptoServiceProvider Using(RSAParameters parameters)
{
RSACryptoServiceProvider encryptor = new RSACryptoServiceProvider();
encryptor.ImportParameters(parameters);
return encryptor;
}
private static byte[] GenerateRandomData()
{
Random rnd = new Random();
byte[] originalData = new byte[10];
rnd.NextBytes(originalData);
return originalData;
}
I use this to encrypt data with the recipient's public key [Using(publicKey).Encrypt(originalData)] so that the receiver only can decrypt the data [Using(privateKey).Decrypt(encryptedData)].
Now I want to reuse asymetric encryption for the following use case: The recipient publishes data and everyone who knows the recipient's public key (which is basically everyone in the system, but nobody outside the system e.g. a protection against leaking readable data to the public) can read it. The publisher uses his private key to encrypt and his public key would be used to decrypt:
byte[] originalData = GenerateRandomData();
byte[] publishedData = Using(privateKey).Encrypt(originalData, false);
byte[] retrievedData = Using(publicKey).Decrypt(publishedData, false);
Debug.Assert(originalData.SequenceEqual(retrievedData));
However this yields a
System.Security.Cryptography.CryptographicException
HResult=0x8009000D
Message=Keyset does not exist.
I do not want to use a different public-private-key-pair for data publishing part, especially in this scenario it means making public a private key. It already sound awkward when typing...
EDIT: Is there an asymetric encryption contained in .NET framework which allows me to use both keys (public and private) in both directions where if one key is used for encryption only the other one can be used to decrypt?
RSA signing is not the same as encrypting with the private key.
PKCS#1 v1.5 signature:
Hash the content with a chosen algorithm.
Create a DigestInfo value to represent the hash.
Apply padding to make a message almost, but not quite, the size of the modulus (details omitted here).
Apply the RSA primitive with the private key
Note that last step doesn’t say “encrypt”.
The RSA classes in .NET do the padding and such for you, so they expose Sign/Verify and Encrypt/Decrypt. You can’t use them for cross purposes, and you can’t use these classes for the RSA primitive (aka “raw RSA”).

Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException when Decrypting RSA in C#

I'm testing RSA in C# dotnet core. I create two RSA objects, one for encrypting and the other for decrypting. I export the public key from the first rsa object and import it for the other object. When the second one decrypt the cipher array, it throws Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException.
The code is below:
String plainstr = "Hello World";
RSA rsa1 = RSA.Create();
RSA rsa2 = RSA.Create();
rsa1.KeySize = 1024;
rsa2.KeySize = 1024;
byte[] cipherbytes = rsa1.Encrypt(Encoding.ASCII.GetBytes(plainstr), RSAEncryptionPadding.Pkcs1);
//If the parameter is true, it works well. But when I use it in an actual project, I won't pass the private key.
RSAParameters parameters = rsa1.ExportParameters(false);
rsa2.ImportParameters(parameters);
//Exception is here.
byte[] plaintbytes = rsa2.Decrypt(cipherbytes, RSAEncryptionPadding.Pkcs1);
Console.WriteLine(Encoding.ASCII.GetString(plaintbytes));
Console.ReadKey();
This is how RSA Encryption works. You can Encrypt with the public key but you can only Decrypt with the private key.
In your example you are encrypting the string with the private key of the rsa1 object, you are copying the public parameters of it to rsa2 and you are trying to decrypt with it.
Maybe you want to do the opposite?

Initializing RSA from String

I am trying to decrypt some text that is encrypted with RSA, I have the public key to do this
`
-----BEGIN RSA PUBLIC KEY-----
MIGWAoGBAMqfGO9sPz+kxaRh/qVKsZQGul7NdG1gonSS3KPXTjtcHTFfexA4MkGA
mwKeu9XeTRFgMMxX99WmyaFvNzuxSlCFI/foCkx0TZCFZjpKFHLXryxWrkG1Bl9+
+gKTvTJ4rWk1RvnxYhm3n/Rxo2NoJM/822Oo7YBZ5rmk8NuJU4HLAhAYcJLaZFTO
sYU+aRX4RmoF
-----END RSA PUBLIC KEY-----
`
How can I load this into RSACryptoServiceProvider because this can only load from XMLString and I do not know how to convert this to Xml format
The key size is 128
I tried to initialize it using the following code
public byte[] Decrypt128(byte[] input)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(128);
rsa.ImportCspBlob(Encoding.ASCII.GetBytes(_longKey));
return rsa.Decrypt(input, true);
}
_longKey is the content between BEGIN and END and also including the BEGIN and END, bot Bad Version of provider.
This is not a duplicate question of How do you convert Byte Array to Hexadecimal String, and vice versa?
I already know how to convert byte to hex and hex to byte, but that in any way does not help me initializing RSACryptoServiceProvider maybe give me example how that would help but at this point it doesn't
You could use BouncyCastle which has a PemReader allowing you to extract the modulus and exponent for the key:
using (var reader = File.OpenText("mykey.key"))
{
var pem = new PemReader(reader);
var o = (RsaKeyParameters)pem.ReadObject();
using (var rsa = new RSACryptoServiceProvider())
{
var parameters = new RSAParameters();
parameters.Modulus = o.Modulus.ToByteArray();
parameters.Exponent = o.Exponent.ToByteArray();
rsa.ImportParameters(parameters);
// Do what you need to do with the RSACryptoServiceProvider instance
}
}
If you don't want to have a dependency on BouncyCastle in your project, once loaded the public key into the RSACryptoServiceProvider using this method you could export it to XML for future use:
string xml = rsa.ToXmlString(false);
File.WriteAllText("mykey.xml", xml);

Encrypting Data using RSA Public and Private Key in C#

I am trying to encrypt a message using RSA public key and decrypt it using my private key. It encrypted the message, but I was not able to decrypt it. The message was still encrypt after the final process. When I exported the private key, it also included the public keys. I tried to remove the public key leaving, but it would not work.
Here are the private and public keys
//This is the public key
private const string public_key = "<RSAKeyValue><Modulus>uznzVPilsR1rWPkpq6m6IALaafDnVZTDDcnEyBD3A/PBx2JZTKM0DTgiTDDwCEmQBNBpPILcIBdtg3aSUgicair+2ksYrVFT+uiy0Zy1nU6qoJ+SsapLKrpCa1zHpV4LMO/pFo4Foqzw0C1FNe56FXo1xj77GPgeYl0MHUVtAUc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
//This is the private and public key.
private const String private_key = "<RSAKeyValue><Modulus>uznzVPilsR1rWPkpq6m6IALaafDnVZTDDcnEyBD3A/PBx2JZTKM0DTgiTDDwCEmQBNBpPILcIBdtg3aSUgicair+2ksYrVFT+uiy0Zy1nU6qoJ+SsapLKrpCa1zHpV4LMO/pFo4Foqzw0C1FNe56FXo1xj77GPgeYl0MHUVtAUc=</Modulus><Exponent>AQAB</Exponent><P>+jPKs9JxpCSzNY+YNanz49Eo/A6RaU1DZWoFm/bawffZOompeL1jzpUlJUIrKVZJkNFvlxE90uXVwjxWBLv9BD==</P><Q>v5CVWKZ5Wo7W0QyoEOQS/OD8tkKS9DjzZnbnuo6lhcMaxsBrCWLstac1Xm2oFNtZgLtrPGbPfCNC5Su4Rz/P5w==</Q><DP>ZnyikmgobqEt20m3gnvcUDxT+nOJMsYYTklQhONoFj4M+EJ9bdy+Lle/gHSLM4KJ3c08VXgVh/bnSYnnfkb20Q==</DP><DQ>sSYGRfWk0W64Dpfyr7QKLxnr+Kv186zawU2CG44gWWNEVrnIAeUeWxnmi41CWw9BZH9sum2kv/pnuT/F6PWEzw==</DQ><InverseQ>XpWZQKXa1IXhF4FX3XRXVZGnIQP8YJFJlSiYx6YcdZF24Hg3+Et6CZ2/rowMFYVy+o999Y5HDC+4Qa1yWvW1vA==</InverseQ><D>Kkfb+8RrJqROKbma/3lE3xXNNQ7CL0F5CxQVrGcN8DxL9orvVdyjlJiopiwnCLgUHgIywceLjnO854Q/Zucq6ysm2ZRq36dpGLOao9eg+Qe8pYYO70oOkEe1HJCtP1Laq+f3YK7vCq7GkgvKAI9uzOd1vjQv7tIwTIADK19ObgE=</D></RSAKeyValue>";
//Encrypting the text using the public key
private RSACryptoServiceProvider cipher = null;
cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(public_key);
byte[] data = Encoding.UTF8.GetBytes(txtUnencrypt.Text);
byte[] cipherText = cipher.Encrypt(data, false);
lblUnencryptMessage.Text = Convert.ToBase64String(cipherText);
// decryptText();
//Trying to decrypt the text using the private key
cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(private_key);
byte[] ciphterText = Convert.FromBase64String(lblUnencryptMessage.Text);
byte[] plainText = cipher.Decrypt(ciphterText, false);
lblDecript.Text = Convert.ToBase64String(plainText);
For example, I encrypted the word "Testing", the encrypted text was
kkqs+UGHNI7/3cKhQvSnJrKzNeCBQX9xHX2VrlyMvnwtszJAoFuViBZlfwmpVhqddnVUrlaqqkD7971E8L3wWltfGetK9nIljeo0GeietLYljoY0Gy3gatU++JPrqajAKxpIB75tvVlKXuYIs0qE3XWZu9bj0zAa4BVT2MhVNQM="
The decrypted text was
dGVzdGluZw==
What am I missing here?
There appears to be nothing wrong with the encryption/decryption code, just how you're handling the decrypted data. Specifically this line:
lblDecript.Text = Convert.ToBase64String(plainText);
You are taking the decrypted data and Base64 encoding it, which is why you get: dGVzdGluZw== (since this is the Base64 encoded version of the string "testing").
You need to use the following instead:
lblDecript.Text = Encoding.UTF8.GetString(plainText);
This should correctly convert the decrypted byte array to a the original string.

Categories

Resources