2

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?

1 Answer 1

3

Use base 64. Signatures consist of random bytes; not all random bytes do however represent a valid character when decoded.

Basically you should only decode strings that were previously encoded.

Sign up to request clarification or add additional context in comments.

5 Comments

Is it possible to convert the hashed message back to original string with my code please?
Sorry i don't understand what you are trying to do. Please be as precise as possible.
Now, I am hashing the message. Then sign the message using private key. Then I just verify using sign and public key. But how can I decrypt the hashed value back to get original message? Actually what I am doing with my application is encrypt the message with private key. Then receiver will decrypt the message using public key. Signature will be sent along as well. How can I achieve it?
You cannot, hashes are one way. Encryption should be performed using the public key of the receiver. If you require less space for the signature use ECDSA.
Thanks so much for support.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.