I am developing a .NET project. I doing encryption to some sensitive data. I am using RSA algorithm for it. I can successfully verify the hash message using private key, public key and signature.
But I am having a problem with converting byte array signature generated by RSA algorithm to string and convert that string back to byte array for verification. But verification fails if I verify signature with byte array that is converted back from signature string. My scenario is below.
This is my complete Cryptography class with RSA algorithm
public class Cryptograph:ICryptograph
{
private string RsaHashAlgorithm { get; set; }
public Cryptograph()
{
this.RsaHashAlgorithm = "SHA256";
}
public RSAParameters[] GenarateRSAKeyPairs()
{
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
RSAParameters publicKey = rsa.ExportParameters(false);
RSAParameters privateKey = rsa.ExportParameters(true);
return new RSAParameters[]{ privateKey , publicKey };
}
}
public byte[] SignRsaHashData(RSAParameters privateKey,byte[]hashOfDataToSign)
{
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
rsa.ImportParameters(privateKey);
var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
rsaFormatter.SetHashAlgorithm(RsaHashAlgorithm);
return rsaFormatter.CreateSignature(hashOfDataToSign);
}
}
public bool VerifyRsaSignature(RSAParameters publicKey,byte[]hashOfDataToSign, byte[] signature)
{
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.ImportParameters(publicKey);
var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
rsaDeformatter.SetHashAlgorithm(RsaHashAlgorithm);
return rsaDeformatter.VerifySignature(hashOfDataToSign, signature);
}
}
}
I test verification. Below is the working code and successfully verified
[TestMethod]
public void VerifyRsaEncryptionSign()
{
var document = Encoding.UTF8.GetBytes("test message");
byte[] hashedDocument;
using (var sha256 = SHA256.Create())
{
hashedDocument = sha256.ComputeHash(document);
}
Cryptograph crypto = new Cryptograph();
RSAParameters[] keys = crypto.GenarateRSAKeyPairs();
RSAParameters privateKey = keys[0];
RSAParameters publicKey = keys[1];
byte[] signature = crypto.SignRsaHashData(privateKey, hashedDocument);
bool verified = crypto.VerifyRsaSignature(publicKey, hashedDocument, signature);
Assert.IsTrue(verified);
}
Above code, unit test passed and successfully verified.
But what I want is I want to convert the signature byte array and convert that string to byte array back for verification like below code.
[TestMethod]
public void VerifyRsaEncryptionSign()
{
var document = Encoding.UTF8.GetBytes("test message");
byte[] hashedDocument;
using (var sha256 = SHA256.Create())
{
hashedDocument = sha256.ComputeHash(document);
}
Cryptograph crypto = new Cryptograph();
RSAParameters[] keys = crypto.GenarateRSAKeyPairs();
RSAParameters privateKey = keys[0];
RSAParameters publicKey = keys[1];
byte[] signature = crypto.SignRsaHashData(privateKey, hashedDocument);
string stringSignature = Encoding.UTF8.GetString(signature);// Converted byte array to string
signature = Encoding.UTF8.GetBytes(stringSignature);//convert string back to byte array
bool verified = crypto.VerifyRsaSignature(publicKey, hashedDocument, signature);
Assert.IsTrue(verified);
}
When I run unit test, verification fails. What is wrong with my code? How can I successfully convert it? I would like to ask additional question as well. Is it possible to convert to hashed message back to original string?