RSA 簽名-PKCS8(.net簽名Java類型的私鑰)

重點說明:.net想要實現對PKCS8格式的私鑰進行簽名的話,需要使用類庫:BouncyCastle.Crypto

下載地址:https://download.csdn.net/download/u011791378/11236710

1:生成公鑰私鑰,我直接使用的是支付寶官網上下載的RSA簽名/驗籤的工具。

string privateKeyPem = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTqFH65mTZLGmm5fWVbgSisLlYpIzWjmOu9lOG9ltH6Ia/Mn5Fnh2iRiYRGs8AzAoNgrOfWy6enK/5lvZa0VWxdw9Hq+mE11pEjh+vo3igvxsHw1Wp2f5cqhMgVT96V2WrSlha6IiQwvFQl72kQXx8sYsTk985OUX78VoUeD8OVXgU0bOXL2JrHfSRNzcQYV1QTrN67Mj6B3QIa4oLUGbB2wxW5jGtxAEOq+WrIyv9Y5IX7oqbHIDMc9L+VG89HnlEVot/Hca+6O1PoDGHygjFIyRXfwZzhaZz8BbAUJCQcWHg0CCY8S4Bj0gWnGiF+U0mezaHukyCZoiM3o3j7RZ5AgMBAAECggEAd82cJoyEysiEOIxghAut6yqkV827D+Kb8rud7eU5DtEVc1BOr8GonZ95B2vPBQCIL4oan3NmEf9jsIjR/cHXW5QUa7yKTeRFM1Z1Uxa5qwMjtVrByHw9K4Y62oMQa/05Wo+JvMjq9TmWfiOAFSOlE68h/pJ+DXnw1Ihw5CbkUoW+lfJkst1ZFSELatX8RMXLccuu06SzGKrnJYtGX3WtTXhs4ShCGuHqowQNzR8UyNPL5tJ1UQTeX8yi6NKkptcnb3IxPOCKDuogF97W/yEXeSxuC2UJfXEvc8fvEQ/D0MuhhWokK8oYoKJ0iMWkf7TeGJaWHB9+XcCJnlks7PXOmQKBgQDKYG1DT840M85qMQmEI+LzGZ348wbrF/JThLHqe66Wsyb+qlnrqRLADRY0u0BMQrQDLq/h2m/3YQ1rTkkHLVfjyi+SGb98JxqEIP1LZ9bzlY4lgfmhjjiGwspC4DFUg+QhyqUEEgziDlP74H4Io/dW1PVm45Hy9NcatDhPoXnPwwKBgQC6yDGpukUTDQ8fF7Ivd96xHzDTpVrGkLgucfosyFrazDBquAKkuyNd41PsOa+8a8Z2KYZQ2DI3Q4DQNeVsbQp3Ik+Q13hj9THfBN8zIE4td+T+uChit6D3fzJZv8F3Jc+IglbvFs/JEBL+5WjT4jtv7rCUJrw3Z0MnLS+mMRr5EwKBgHLg/eUh3jm/1sJtB6vc+y1oM0ZoHltBgqtqPdyPTPH6zH3vkY+2sBAY3awdR0iC7NCJpgmdB8Xzb7yj+cx7LtL9qLdUql/9io3KdD5juZ8YHFKqT1wn8Wp+FHaV8Sq6m7ua3sVKwclovL/UFXcuLG87//nh4K170scz2mtJjG4lAoGAeGS/9joVegEp5Q2+EfC+/wYuz80+pMz1myJmcmU2gt+oubEgKxRg6Iy2NIa+asJBazq60/N28r41EoAbAHeMjlv0U1U/yZZrbehTAj5phc9JMJJ9nZvlSoKXbtg2GNmrWr9Az92xU1VkGR7AIgsp6q087lHFciTCWUc79nCihTcCgYEAlzFctq2NosJduAivpeJZGR7i0mR1ciypJiKDllrkuvP5qKMYb6vKAGgvnMm9a5rdj32ejYtVZRZhU9pd50U9np/YbILu1sR/wXOzm4NCq7L4JDW/vJV+kMpkJu/mIRo00zp84+JGGjDCA3wvlQ/iVpa4hxPNjjlKfIlPLEIbMX8=";
string publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk6hR+uZk2SxppuX1lW4EorC5WKSM1o5jrvZThvZbR+iGvzJ+RZ4dokYmERrPAMwKDYKzn1sunpyv+Zb2WtFVsXcPR6vphNdaRI4fr6N4oL8bB8NVqdn+XKoTIFU/eldlq0pYWuiIkMLxUJe9pEF8fLGLE5PfOTlF+/FaFHg/DlV4FNGzly9iax30kTc3EGFdUE6zeuzI+gd0CGuKC1BmwdsMVuYxrcQBDqvlqyMr/WOSF+6KmxyAzHPS/lRvPR55RFaLfx3GvujtT6Axh8oIxSMkV38Gc4Wmc/AWwFCQkHFh4NAgmPEuAY9IFpxohflNJns2h7pMgmaIjN6N4+0WeQIDAQAB";
string signType = "RSA2";

記得要對公鑰私鑰去空格換行操作哦

注意:此處應該爲PKCS8格式的私鑰!!!

2:生成待簽字符串

Dictionary<string, string> ParamInfo = new Dictionary<string, string>();
ParamInfo.Add("timestamp","20191112135000");
ParamInfo.Add("noncestr","123sdsf");
ParamInfo.Add("name", "張三");

//對報文中出現簽名域(signature)之外的所有數據元按照key的ascii順序排序,然後以&作爲連接符拼接成待簽名串。
string signContent = SignUtil.GetSignContent(ParamInfo);

生成待簽字符串的可參考此方法

        /// <summary>
        /// 待簽字符串
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static string GetSignContent(IDictionary<string, string> parameters)
        {
            // 第一步:把字典按Key的字母順序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();

            // 第二步:把所有參數名和參數值串在一起
            StringBuilder query = new StringBuilder("");
            while (dem.MoveNext())
            {
                string key = dem.Current.Key;
                string value = dem.Current.Value;
                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
                {
                    query.Append(key).Append("=").Append(value).Append("&");
                }
            }
            string content = query.ToString().Substring(0, query.Length - 1);

            return content;
        }

3:簽名

                    string signatureNew = string.Empty;
                    string SignerSymbol = string.Empty;
                    if (signType == "RSA")
                    {
                        SignerSymbol = "SHA1WithRSA";
                    }
                    else
                    {
                        SignerSymbol = "SHA256WithRSA";
                    }
                    SignHelper helper = new SignHelper();
                    helper.RSASigning(Encoding.UTF8, SignerSymbol);
                    signatureNew = helper.Sign(signContent, privateKeyPem);

4:驗籤-不在簽名步驟內。。。

bool check = false;
check=helper.Verify(signContent, signatureNew, publicKey);

check爲true 則驗籤成功,爲false則驗籤失敗。

5:把簽名放入報文集合中!這樣整個報文才算簽名完成。

 

SignHelper類庫(需要引用BouncyCastle.Crypto

public class SignHelper
    {
        public Encoding encoding = Encoding.UTF8;
        public string SignerSymbol = "MD5withRSA";
        public void RSASigning() { }
        /// <summary>
        /// 簽名模式
        /// </summary>
        /// <param name="e">Encoding</param>
        /// <param name="s">MD5withRSA,SHA256WithRSA</param>
        public void RSASigning(Encoding e, string s)
        {
            encoding = e;
            SignerSymbol = s;
        }
        private AsymmetricKeyParameter CreateKEY(bool isPrivate, string key)
        {
            byte[] keyInfoByte = Convert.FromBase64String(key);
            if (isPrivate)
                return PrivateKeyFactory.CreateKey(keyInfoByte);
            else
                return PublicKeyFactory.CreateKey(keyInfoByte);
        }
        /// <summary> 
        /// 數據加密 
        /// </summary> 
        /// <param name="content">待加密字符串</param>
        /// /// <param name="privatekey">私鑰</param> 
        /// <returns>加密後字符串</returns> 
        public string Sign(string content, string privatekey)
        {
            ISigner sig = SignerUtilities.GetSigner(SignerSymbol);
            sig.Init(true, CreateKEY(true, privatekey));

            byte[] bytes = encoding.GetBytes(content); //待加密字符串
            sig.BlockUpdate(bytes, 0, bytes.Length);
            byte[] signature = sig.GenerateSignature(); // Base 64 encode the sig so its 8-bit clean 
            var signedString = Convert.ToBase64String(signature);
            return signedString;
        }

        /// <summary> 
        /// 驗證簽名 
        /// </summary> 
        /// <param name="content">待簽名的字符串</param>
        /// <param name="signData">加密後的文本</param> 
        /// <param name="publickey">公鑰文本</param> 
        /// <returns>是否一致</returns> 
        public bool Verify(string content, string signData, string publickey)
        {
            ISigner signer = SignerUtilities.GetSigner(SignerSymbol);
            signer.Init(false, CreateKEY(false, publickey));
            var expectedSig = Convert.FromBase64String(signData);  
            var msgBytes = encoding.GetBytes(content); 
            signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
            return signer.VerifySignature(expectedSig);
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章