So, in my C# app I have the following code to encrypt the data:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
namespace TEST
{
public class RSAEncrypter
{
private static RSACryptoServiceProvider RSA;
private RSAParameters _privateKey;
private RSAParameters _publicKey;
public RSAEncrypter()
{
RSA = new RSACryptoServiceProvider(2048);
_privateKey = RSA.ExportParameters(true);
_publicKey = RSA.ExportParameters(false);
}
public string Encrypt(string plainText, string publicKey)
{
RSA.FromXmlString(publicKey);
_publicKey = RSA.ExportParameters(false);
RSA.ImportParameters(_publicKey);
var data = Encoding.Unicode.GetBytes(plainText);
var cypher = RSA.Encrypt(data, false);
return Convert.ToBase64String(cypher);
}
// Gets the privatekey as a string
public string PrivateKeyString()
{
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, _privateKey);
return sw.ToString();
}
}
}
Which gives me, for example, a key in the following format (as a string):
<?xml version="1.0" encoding="utf-16"?>
<RSAParameters xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Exponent>AQAB</Exponent>
<Modulus>38Z4+7H1ADzMPO8z5+QdxXS21YBEaq9Xacf7dHFXUpK72SUAIYnfijc5RDSgGFismTNlrrOa7m/6+iIWS/yB7+esvIjgfSFm+QU2aeC16NisMuw+KvPeEr8CVMjh8F5YW1ST4qKXHXG6qIe/FM2LPVGV92O9WO1ATIDcATO8UU2rJgrxKMdmE9fawqmy/j7fwI1+FL6LCNgdvgZ3OOLLwHVcyOyj7ibiIUQAcw10qW0I4MBnQL5V8udKrhKXKoVE6rsfLZoBC9rBD62ckB7CJfMsGcAVffBvnd7SRJiTFEEPVZFqzyGk0BOeqbJkHbzKNytNkUjnFQlDX9tSLCtufQ==</Modulus>
<P>+jlZUY/lv0bMWbcWVXZ+moDF96ZQ+uKHMbpAMN18ByRmZSLZ9CeHTNEkoudOzB6R9wN8xyEmnCrDZujSB65uBILdJvsJk8TYBThp5RBbBZ1YQb30CcxhsMX2s6Gwze8CoXmBU5as6tMDh+tBpxxeYxE/crS3rP7kAM2Lr88cILM=</P>
<Q>5PDUdn/RB8dhxkjSFZS0MtrefVgYmoDNjN9O+Ru7ZzNz7eqig1zLlKytDQzmpaIv6Zvrn5Y5TBaFDp1BTVLAStu8e/RU4i7qWVu6Xm83xtgB4NDULXStyYqpeZhyilD4BsfIYeRyZ3A9wUyACQ6CU3GxuIczWYkfT3HmSy5ebA8=</Q>
<DP>nEH/8x0nXeF6b3QUMF6FBTrxZYuo+mNIBdfHijxl3ZfvkazH6t5cca4RcOF9pZ5ZjKXS4A9lqxRRXgx6TG2zKoIGVPdjrbG5LNlj17X1AXaWzMcwhIXrY5bcTqTkYlWlkOztxCNN7H7Fr7VMFG10y+zTcHBGW3P5Mj8pwipV6F0=</DP>
<DQ>DMkWVHfW6KRN5ZDzipj/Z0ep3T4qQZan5BIkiuztjlnlQ4gzAzsPc4IhN/VcfCuOmXFHu2XcVU98ptBJcVQJwSR8Zj/C7c7I76ybv+JeLxCpKjD/aHp3qiXASTYmT2suLtLBchYb/YLbMAxhqh/RT2+uCSwjxgBOa1VlExXH2Ck=</DQ>
<InverseQ>zlFNPMXsmgjWz0rA5y3stzoKDiw0mbb1rU6iSXKKOZz5djokAX1tjtcwUbzdv3I5x8m+3K1qprXURUYbZXf+ubwkoYiG4WaJDWhZ+y33Q8iK87BUKy6Q062F4XryBVagCJHKMNStiiMmFB9IdbDu/wbYh52BjrwhwncLOEYaSaQ=</InverseQ>
<D>YQvsEAv/WtkDIjIC6sBtgOK7ICB+i137pO6LyNYWrsLgIK4BPopSndiRR1kjTSu3vsEhigBuYpXB3JTH4rBhka+BpEogQWQpCjoOfSBtA8xj8bmuxGX6m1qnIin0gpAH9aPaduFYc/aMouYsIlN53V/yj9V7moNZ7VO9FfBf7UnX7yTc2/fvXz9atXepQmir2YOO41Z5KgytSF1M7R3eZq1GLTnaqRK+LCQ5cKkxqcIAtUX7BZgkLnHZs3zqLo998gXbogmkqxB4NWc9bwWjybC1CMWyZeiRuaw/Wye4GbNmpM7sfsB7GINndwCSqfJzwSetGCSca8x2wkms+5zOaQ==</D>
</RSAParameters>
So how could I decrypt a message in PHP using this key?
I found this in PHP: openssl_private_decrypt but it doesn't accept the key in this format apparently.
Ok, I found out!
So, first you need to convert the key from XML to PEM format. I found this GITHUB code which is very usefull doing that: Exports RSA key pair to PEM format.
Next, after you encrypted the data utilizing my original code in the Question, you need use php's method base64_decode before utilizing the method openssl_private_decrypt. So, in the end you'll have something like this:
<?php
$encryptedData = '
b9+nktWSdlYQWiuswcT49JJdt1mmZj87Gwwydkpiu2Xbf3n1Nc+xE5whSzgfTIIthQEVssCUk/UfNsyN2iC37nkxcQe4Xu6KsiWFYvCRZmxww24p/qi43isd1ijCS6wajrJbrpq2tvLzBZ7KhrYkEt3qPbanRRslJauzaCW8MT42HotFl7mVKJjj5p+U6p5dklkm0Uxn36a9eB8+Nt8kSum1YcUbkrS0TRhmorQxifNY99yEju3KeISq5+946tKpW+Efau0CvUF/V5mKn203T5MdO8x5z7VFejHW6dB6oDxTh9EeEyEAPPRBz734wtZxCOVODd39Ttnk6FfnnWat8w==
';
$private_key = '
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwGbWRx8kEz5+BHt5f8/R4ka7AOBGbP1YjfhY33eUQzsh6Ygl
jAvPYXmopaSEOLWAjq/TTCGXGmSfZi0DRPGeSnNXzU6nUu1qQBC5sQYIPSph/lEV
S7jv8isVO9/vH+TGCwE0CeGiQt1QP/m72Vaux3U6nt6ddVat3rpHy4FVuuDHKF58
9HQakf5cMCz4wei4y71U/tLIj1F7P5TRqSdKMB4ZLYLDbX+32OEPMEP6DJEysAiC
oRdpBR/KCOlH3QHEF0RDuTbdgL6f8oAuN2Wvr+p+f1lnkld08+gyKma9cEBpeIB7
cjBeNNcImyhXfp8VBjjZNd//ikt7jnDle30MWQIDAQABAoIBADuxbDfCrKGf2N8x
I+AIrTiD807xRkhYTdo2O/SRGBnHxdy7ldKec2fto+pIYZFqlokueeL75PKWV3IO
8x23zQGSSaJ0DavH5xgbWFFY6sN3W9HYfD/zD9bVkQ/ziTAe/Wa6p9eM/pe6LES9
CZADudQ+RcK2lKmsC+O3bcDwzpVczzuZ1s29F6Jc2L0Q7e1ce9FfBmhl/faei7ro
5DWV30+AqhdwPppMhOWFS/walro8Sq90Kz0chaU6N1vVBEdo4dSLKYapyxJwAHhm
HfNkA+wMrsMXGd9eKpi4u8AupnJYypFdBaEEgrKIbg21LLRTyx1fFKXWdE0puG7H
0GVfoNUCgYEAxoaCzv7LslAOa8bZwGVxcvnE0tIafPwXyOldH/jqeXf53I1gOmFM
dI143wawKQES8CvrbedzP/5tNVZhdrOOekTRM61yw3xSUYY5e8Ngt/gn4KyQ0nA5
X75QjtC6VxNM6ssFpyUxQT95lvTo13avrVjhnGt3raNxwTgiqJjvTfsCgYEA+Bp5
FElve0NnfvkpYeffuF6E3mTRS44IH7qRTFrpXh31zwMxE6K3cltbRtHtuf5/7DmR
XpbeogxG4Bzzw/Y7DodV3V82ApIzyhFkN5PPfg5mR/W8cia82Q3QsRMpjYTo9TBZ
aiAsTbUz8E6KaFrS64V6KbRl84EE8XBaG7tvYrsCgYBZ4TZBzvub7EDLLMkTIRpe
6pPgurzBT0TZckX2HrTRb68Q2nTxmXGK5y4NEzMYLWNMlyXMqVf1ZhQ9bLFNk3dz
BcsNMX7e4F9Ih5No5Aja4Z/0SUx76dEf9sL0Fa33lEZjmq0hgmYtWzaKULFGM3bP
7YifT8xsMa5jwy111V+qlwKBgQCjtHwN+cKYd8pTir5WfrQsqBlN0QIUs3wCy4zR
7+6qDmTCGl4IkcYvq74Xha8xmY745KdZ3Xy7OhSODix+MfuXw47RieBOY//OJhmV
Xm97wq6Ubr3QKGVVZvs7y+QQIBHCrwtgriftglHqDzjeUId5plIMMJ9Qw+HqGXMr
d0qwvwKBgQCjNuhKMHGqG6DuYiLQjJVHA6aG87K5tfNNC8yQPOIbkIJTlSzGQIkm
66wA2PSCI+yRixm+gZWGdVcYuVvcfTHLsledLocTWBRf/2VAGlqZg1ewybGrrixF
05KXg9DcAK9HFyZryFZAXtLyAoRaS1ElcSVBtLggQreGsr8fIM5Fvw==
-----END RSA PRIVATE KEY-----
';
openssl_private_decrypt(base64_decode($encryptedData), $decriptedData, $private_key);
echo var_dump($decriptedData);
Related
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.
I have some code in PHP:
function get_RSAencrypt($public_key) {
global $config;
$rsa = new phpseclib\Crypt\RSA();
$rsa->setEncryptionMode(phpseclib\Crypt\RSA::ENCRYPTION_PKCS1);
$rsa->loadKey($public_key);
$requestkey = base64_encode($rsa->encrypt($config['momo_key']));
return $requestkey;
}
My public key(for eg.)
-----BEGIN RSA PUBLIC KEY-----
MEgCQQDjtTNZJnbMWXON/mhhLzENzQW8TOH/gaOZ72u6FEzfjyWSfGsP6/rMIVjY
2w44ZyqNG2p45PGmp3Y8bquPAQGnAgMBAAE=
-----END RSA PUBLIC KEY-----
PHP code work
Then I tried to find some example for C# .NET Framework 4.6, but not work.
Can someoone provide me a link?
Try this:
using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
class Test
{
static void Main()
{
var key = #"-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu
KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm
o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k
TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7
9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy
v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs
/5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00
-----END RSA PRIVATE KEY-----";
var ciphertext = "L812/9Y8TSpwErlLR6Bz4J3uR/T5YaqtTtB5jxtD1qazGPI5t15V9drWi58colGOZFeCnGKpCrtQWKk4HWRocQ==";
var ciphertextBytes = Convert.FromBase64String(ciphertext);
var rsa = RSA.Create();
var rx = new Regex("-+[^-]+-+");
key = rx.Replace(key, "")
.Replace("\r", "")
.Replace("\n", "");
var keyBytes = Convert.FromBase64String(key);
rsa.ImportRSAPrivateKey(keyBytes, out _);
var plaintextBytes = rsa.Decrypt(ciphertextBytes, RSAEncryptionPadding.Pkcs1);
var plaintext = Encoding.Default.GetString(plaintextBytes);
Console.WriteLine(plaintext);
}
}
ImportRSAPrivateKey wasn't introduced until .NET Core 3.0+ but since you're using C# .NET Framework 4.6 I think you're probably good!
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 ^^
We have private key (GOST3410-2012).
But we can't read it using BouncyCastle 1.8.6.1
Here is a key data:
-----BEGIN PRIVATE KEY-----
MIGiAgEAMCEGCCqFAwcBAQECMBUGCSqFAwcBAgECAQYIKoUDBwEBAgMEQIXnWrZ6
ajvbCU6x9jK49PgQqCP00T/lW3laXCXueMF8X4Q1y3N9zfOJT2s/IgyPJVrUhgtO
1Akp+Roh8bCPPlqgODA2BggqhQMCCQMIATEqBCi72ZvrBVW6mFL/bQeXeMTf8Jh8
p/diI7Cg8ig4mXg3tsIUf4vBi61b
-----END PRIVATE KEY-----
And here is a code to read it:
const string keyPath = "D:\\testkey\\priv.key";
using (var textReader = File.OpenText(keyPath))
{
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(textReader);
var pemObj = pemReader.ReadPemObject();
var seq = (Asn1Sequence)Asn1Object.FromByteArray(pemObj.Content);
var keyInfo = PrivateKeyInfo.GetInstance(seq);
var akp = Org.BouncyCastle.Security.PrivateKeyFactory.CreateKey(keyInfo);
}
this code provide exception: "DER length more than 4 bytes: 103".
Does anyone knows how to read it?
If you make your key with OpenSSL, try to add the following parameter in the "gost_section" of your OpennSSL config file:
GOST_PK_FORMAT = LEGACY_PK_WRAP
then export the key again
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);