RSA签名验证

nuptgis 2014-03-11 09:32:56
公钥:
publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8rPqGGsar+BWI7vAtaaDOqphy41j5186hCU9DcchV4HWiv0HvQ3KXAEqHfZiAHZSyMSRMmDZVnqJwCVWFvKUPqU1RsCPZ9Imk+9ZXVkM3DDdw74v/s6YMNx8cTuxybRCJUfOKbyC79cnHgmQqqkODv+EnprBtNKE4k8g90jNmbwIDAQAB";


用到的验证方法:
  
/// <summary>
/// 验证RSA签名
/// </summary>
/// <param name="str_DataToVerify">待签名的字符串</param>
/// <param name="str_SignedData">对方生成的RSA签名</param>
/// <param name="str_Public_Key">对方公钥</param>
public static bool VerifySignedHash(string str_DataToVerify, string str_SignedData, string str_Public_Key)
{

byte[] SignedData = Convert.FromBase64String(str_SignedData);
ASCIIEncoding ByteConverter = new ASCIIEncoding();
byte[] DataToVerify = ByteConverter.GetBytes(str_DataToVerify);
try
{
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
byte[] pubKeyBytes = Convert.FromBase64String(str_Public_Key);
RSAalg.ImportCspBlob(pubKeyBytes);
return RSAalg.VerifyData(DataToVerify, new SHA1CryptoServiceProvider(), SignedData);
}
catch (CryptographicException e)
{
return false;
}
}

其中RSAalg.ImportCspBlob(pubKeyBytes);报错提示:不正确的提供程序版本。
请问是否是解析公钥这块有问题?如能解决,给出代码示例。
...全文
629 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjtu_chenchen 2015-08-16
  • 打赏
  • 举报
回复
你好,请问怎样将csp设为默认,让防火墙Ipsec调用
nuptgis 2014-03-13
  • 打赏
  • 举报
回复 1
已解决,
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="content">待签名字符串</param>
        /// <param name="signedString">POST过来的签名</param>
        /// <param name="publicKey">公钥</param>
        /// <param name="input_charset">编码格式</param>
        /// <returns></returns>
        public static bool verify(string content, string signedString, string publicKey, string input_charset)
        {
            bool result = false;
            try
            {
                Encoding code = Encoding.GetEncoding(input_charset);
                byte[] Data = code.GetBytes(content);
                byte[] data = Convert.FromBase64String(signedString);
                RSAParameters paraPub = ConvertFromPublicKey(publicKey);
                RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
                rsaPub.ImportParameters(paraPub);

                SHA1 sh = new SHA1CryptoServiceProvider();
                result = rsaPub.VerifyData(Data, sh, data); 
                return result;
            }
            catch (Exception ex)
            {  
                return false;
            }
        }

   #region 解析.net 生成的Pem
        private static RSAParameters ConvertFromPublicKey(string pemFileConent)
        {

            byte[] keyData = Convert.FromBase64String(pemFileConent);
            if (keyData.Length < 162)
            {
                throw new ArgumentException("pem file content is incorrect.");
            }
            byte[] pemModulus = new byte[128];
            byte[] pemPublicExponent = new byte[3];
            Array.Copy(keyData, 29, pemModulus, 0, 128);
            Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
            RSAParameters para = new RSAParameters();
            para.Modulus = pemModulus;
            para.Exponent = pemPublicExponent;
            return para;
        }
md5e 2014-03-12
  • 打赏
  • 举报
回复
public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData) { try { byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter); RSACryptoServiceProvider key = new RSACryptoServiceProvider(); key.FromXmlString(p_strKeyPublic); RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key); deformatter.SetHashAlgorithm("MD5"); byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData); if (deformatter.VerifySignature(rgbHash, rgbSignature)) { return true; } return false; } catch { return false; } }
gomoku 2014-03-12
  • 打赏
  • 举报
回复
你例子中的publicKey用的是ASN.1 DER编码,因此不能直接用ImportCspBlob(它使用另外一种格式)。 你可以用在线工具进行解码: http://lapo.it/asn1js/ 得出的结果类似:

SEQUENCE(2 elem)
--SEQUENCE(2 elem)
----OBJECT IDENTIFIER 1.2.840.113549.1.1.1
----NULL
--BIT STRING(1 elem)
----SEQUENCE(2 elem)
------INTEGER(1024 bit) 1324925806459412787721713702712958489781723…
------INTEGER 65537
其中最后的65537就是publicKey中的Exponent,而那个1024bit的数据就是publicKey中的Modulus。 如果是实时解码,可能你要写一个DER解析器。 如果是一次性解码,可以投机直接裁出:

byte[] bytes = Convert.FromBase64String(publicKey);

if (bytes.Length != 0xa2)
{
    throw new NotImplementedException();
}
if (!bytes.Skip(bytes.Length - 5).SequenceEqual(new byte[]{2,3,1,0,1}))
{
    // 确认Exponent在最后,并且是65537
    // 其中2表示ASN整数型,3表示整数数据的字节数,1,0,1就是0x101,就是65537
    throw new NotImplementedException();
}

RSAParameters rsaParam = new RSAParameters()
{
    Exponent = new byte[]{ 1, 0, 1 },  //65537
    Modulus = bytes.Skip(bytes.Length - 5 - 1024).Take(1024).ToArray(),  // BCACFA...
};

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParam);

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧