Encrypt password by using Public Key (.pem) file - c#

Now I have a Public Key(.pem) file and password to encrypt.
-----BEGIN PUBLIC KEY-----
.....
...
...
-----END PUBLIC KEY-----
I would like to get byte[] values for encrypted password.
It doesn't get any error but return byte[] values is seem to wrong.
Below are coding current my using one, pls help me or advise me if I'm going wrong.
Really appreciate for your help!!
private static UnicodeEncoding _encoder = new UnicodeEncoding();
public byte[] getPem(string pemFile, string password)
{
byte[] encryptData;
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] Exponent = { 1, 0, 1 };
RSAParameters rsaParam = rsa.ExportParameters(false);
rsaParam.Modulus = Convert.FromBase64String(File.ReadAllText(pemFile).Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", ""));
rsaParam.Exponent = Exponent;
rsa.ImportParameters(rsaParam);
var dataToEncrypt = _encoder.GetBytes(password);
encryptData = rsa.Encrypt(dataToEncrypt, false);
return encryptData;
}

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!

How to Sign a own RSA private key with MD5 Hash data in C#

I want to sign an own private key with MD5 Hash data in c#
I have private key in .pem format
I do not know how I pass my Private key in this
I need to sign my hash data with own private key to generate the signature
Any help appreciate
string test = cla.MD5Hash("appid=A001channel=ae0e6jm55qlq1o7fee_type=THBmch_order_no=201601031138001nonce_str=13572468total_fee=100");
string MD5HashData = "8b4f789f8bb0bdf962e8274d40c3864e";
string privateKey1 = "-----BEGIN RSA PRIVATE KEY-----MIICYQIBAAKBgQDVex7K03NAnr7Jm15z50drNmPuYWCThI0cmg+tpSpH6gHNoe8H6Xm4fJpx+xhdERa7WnO3MZLHFu0LTvVweq0auCiBkYjV6x8tDG1F41nWcPOSHnH/ZpZur+4u/tJzCTM4xWw9ayBNSI6syankeZzyHMz7DtQulDjWyUzwAYyiDmpRBiSxYbUnBfcDL7uiNbwaGm1dB8pEnJIw/00T69DjdcKQSH57F5HAkRHQ4j1Yo1Tz8lNCDmoK9JW4RtUM4ABimfo3X3/95XXGthGgOfH0XXY8FG6jSEypha6FkvGNzUsnQsnA+O8lBjuGmnFPw==-----END RSA PRIVATE KEY-----";
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey = RSA.ToXmlString(false);
string privateKey = RSA.ToXmlString(true);
// RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(privateKey);
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
RSAFormatter.SetHashAlgorithm("SHA1");
SHA1Managed SHhash = new SHA1Managed();
byte[] SignedHashValue = RSAFormatter.CreateSignature(SHhash.ComputeHash(new UnicodeEncoding().GetBytes(MD5HashData)));
string signature = System.Convert.ToBase64String(SignedHashValue);

Error "InvalidCipherTextException: data start wrong 64" with Bouncy Castle

I am encrypting and decrypting some Data using BouncyCastle, but when the lenght of the word is too long (i don´t know exactly the value), i got this error "InvalidCipherTextException: data start wrong 64"
This is my Class of Encription:
public static class Crypto
{
public static IAsymmetricBlockCipher CriarCipher(byte[] encodingParam)
{
// Creating the RSA algorithm object
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), encodingParam);
return cipher;
}
public static AsymmetricCipherKeyPair CreatePair()
{
RsaKeyPairGenerator rsaKeyPairGnr = new RsaKeyPairGenerator();
rsaKeyPairGnr.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keyPair = rsaKeyPairGnr.GenerateKeyPair();
return keyPair;
}
public static byte[] Encriptar(RsaKeyParameters publicKey, string texto, byte[] encodingParam)
{
// Creating the RSA algorithm object
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), encodingParam);
var palavrabyte = Encoding.UTF8.GetBytes(texto);
// Initializing the RSA object for Encryption with RSA public key. Remember, for encryption, public key is needed
cipher.Init(true, publicKey);
byte[] ciphered = cipher.ProcessBlock(palavrabyte, 0, palavrabyte.Length);
return ciphered;
}
public static string Decriptar(RsaKeyParameters privateKey, string txtEncript, byte[] encodingParam)
{
// Creating the RSA algorithm object
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), encodingParam);
// Initializing the RSA object for Encryption with RSA public key. Remember, for encryption, public key is needed
cipher.Init(false, privateKey);
byte[] txtEncriptBytes = Convert.FromBase64String(txtEncript);
byte[] deciphered = cipher.ProcessBlock(txtEncriptBytes, 0, txtEncriptBytes.Length);
string decipheredText = Encoding.UTF8.GetString(deciphered, 0, deciphered.Length);
return decipheredText;
}
}
This is the code for OAEPE Encoding:
SHA256Managed Hash = new SHA256Managed();
byte[] ParamOEAP = Hash.ComputeHash("Example" + anotherdata);
And the class SHA256Managed:
public class SHA256Managed
{
public byte[] ComputeHash(string text)
{
Sha256Digest dig = new Sha256Digest();
byte[] msgBytes = Encoding.UTF8.GetBytes(text);
dig.BlockUpdate(msgBytes, 0, msgBytes.Length);
byte[] result = new byte[dig.GetDigestSize()];
dig.DoFinal(result, 0);
return result;
}
}
When i encrypt the word, per example, "Subtracão de Incapazes", the decryption its ok.
When i encrypt the word, per example, "Estelionato por Emissão de Cheque sem Suficiente Provisão de Fundos", the decryption brokes in the Decriptar codeline:
byte[] deciphered = cipher.ProcessBlock(txtEncriptBytes, 0, txtEncriptBytes.Length);
What i am doing wrong ?
Changing on CreatePair the line:
rsaKeyPairGnr.Init(new KeyGenerationParameters(new SecureRandom(), 2048))
From 1024 to 2048 !! Now, big phrases are decrypted.

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;
}

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