在.NET C#中再次将RSA算法的字节数组签名转换为字符串并返回到字节数组

时间:2016-07-11 06:38:47

标签: .net encryption cryptography rsa encryption-asymmetric

我正在开发一个.NET项目。我对一些敏感数据进行加密。我正在使用RSA算法。我可以使用私钥,公钥和签名成功验证哈希消息。

但是我遇到了将RSA算法生成的字节数组签名转换为字符串并将该字符串转换回字节数组以进行验证的问题。但是,如果我使用从签名字符串转换回的字节数组验证签名,则验证失败。我的情况如下。

这是我完整的带有RSA算法的密码学课程

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

    }

我测试验证。以下是工作代码并已成功验证

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

以上代码,单元测试通过并成功验证。

但我想要的是我想转换签名字节数组并将该字符串转换回字节数组以进行验证,如下面的代码所示。

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

当我运行单元测试时,验证失败。我的代码出了什么问题?我怎样才能成功转换它?我想问一下其他问题。是否可以将哈希消息转换回原始字符串?

1 个答案:

答案 0 :(得分:2)

使用base 64.签名由随机字节组成;然而,并非所有随机字节都表示解码时的有效字符。

基本上你应该只解码以前编码的字符串。