本帖最后由 nuptgis 于 2014-03-11 21:38:44 编辑

解决方案 »

  1.   

    你例子中的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);
      

  2.   

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

  3.   

    已解决,
            /// <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;
            }