【问题标题】:Convert byte array signature of RSA algorithm to string and back to byte array again in .NET C#在.NET C#中将RSA算法的字节数组签名转换为字符串并再次转换回字节数组
【发布时间】:2016-11-13 00:33:48
【问题描述】:

我正在开发一个 .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);
        }

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

【问题讨论】:

    标签: .net encryption cryptography rsa encryption-asymmetric


    【解决方案1】:

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

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

    【讨论】:

    • 是否可以使用我的代码将散列消息转换回原始字符串?
    • 对不起,我不明白你在做什么。请尽可能准确。
    • 现在,我正在对消息进行哈希处理。然后使用私钥对消息进行签名。然后我只是使用签名和公钥进行验证。但是如何解密散列值以获取原始消息?实际上我对我的应用程序所做的是用私钥加密消息。然后接收者将使用公钥解密消息。签名也会一起发送。我怎样才能实现它?
    • 你不能,哈希是一种方式。应使用接收方的公钥进行加密。如果您需要更少的签名空间,请使用 ECDSA。
    • 非常感谢您的支持。
    猜你喜欢
    • 2010-11-28
    • 2011-06-23
    • 2021-12-02
    • 2011-12-18
    • 1970-01-01
    • 2021-11-11
    • 2012-02-24
    相关资源
    最近更新 更多