C#使用RSA签名和验证签名.编码问题 [英] C# Signing and verifying signatures with RSA. Encoding issue

查看:84
本文介绍了C#使用RSA签名和验证签名.编码问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与2011年的一种形式非常相似,即签名并使用RSA C#验证签名.但是,当我将签名数据和原始消息进行比较时,我也会出错.请指出我的错误.

My question is pretty similar to the one form 2011, Signing and verifying signatures with RSA C#. Nevertheless, I also get false when I compare the signed data and the original message. Please point on my mistake.

代码:

 public static void Main(string[] args)
    {            

        //Generate a public/private key pair.  
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

        //Save the public key information to an RSAParameters structure.
        RSAParameters RSAPublicKeyInfo = RSA.ExportParameters(false);
        RSAParameters RSAPrivateKeyInfo = RSA.ExportParameters(true);    

        string message = "2017-04-10T09:37:35.351Z";

        string signedMessage = SignData(message, RSAPrivateKeyInfo);

        bool success = VerifyData(message, signedMessage, RSAPublicKeyInfo);

        Console.WriteLine($"success {success}");

        Console.ReadLine();
    }   

签名方式:

 public static string SignData(string message, RSAParameters privateKey)
    {
        ASCIIEncoding byteConverter = new ASCIIEncoding();

        byte[] signedBytes;

        using (var rsa = new RSACryptoServiceProvider())
        {
            // Write the message to a byte array using ASCII as the encoding.
            byte[] originalData = byteConverter.GetBytes(message);                

            try
            {
                // Import the private key used for signing the message
                rsa.ImportParameters(privateKey);

                // Sign the data, using SHA512 as the hashing algorithm 
                signedBytes = rsa.SignData(originalData, CryptoConfig.MapNameToOID("SHA512"));
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e.Message);
                return null;
            }
            finally
            {
                // Set the keycontainer to be cleared when rsa is garbage collected.
                rsa.PersistKeyInCsp = false;
            }
        }
        // Convert the byte array back to a string message
        return byteConverter.GetString(signedBytes);
    }

验证方法:

public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey)
    {
        bool success = false;
        using (var rsa = new RSACryptoServiceProvider())
        {
            ASCIIEncoding byteConverter = new ASCIIEncoding();

            byte[] bytesToVerify = byteConverter.GetBytes(originalMessage);
            byte[] signedBytes = byteConverter.GetBytes(signedMessage);

            try
            {
                rsa.ImportParameters(publicKey);

                success = rsa.VerifyData(bytesToVerify, CryptoConfig.MapNameToOID("SHA512"), signedBytes);
            }
            catch (CryptographicException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                rsa.PersistKeyInCsp = false;
            }
        }
        return success;
    }

基本上,问题在于字符串到byte []的编码.我在ASCIIEncoding和UTF8Encoding上遇到了同样的问题.

Basically the problem is with string to byte[] encoding. I get the same problem with ASCIIEncoding and with UTF8Encoding.

提前谢谢!

推荐答案

您不能在已编码的消息上使用 ASCIIEncoding ,因为它包含无效ASCII字符的字节.存储编码消息的典型方法是在base64字符串中.

You cannot use ASCIIEncoding on the encoded message because it contains bytes which are invalid ASCII characters. The typical way you would store the encoded message is in a base64 string.

SignData 中,使用以下代码将字节数组编码为字符串:

In SignData, use the following to encode the byte array into a string:

return Convert.ToBase64String(signedBytes);

并在 VerifyData 中,使用以下代码将字符串解码回相同的字节数组:

and in VerifyData, use the following to decode the string back to the same byte array:

byte[] signedBytes = Convert.FromBase64String(signedMessage);

这篇关于C#使用RSA签名和验证签名.编码问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆