java和C#使用證照對引數簽名、加密

AnCoo0303發表於2018-04-25

    基於C#平臺發起支付請求,提交到java平臺進行支付的過程,涉及到雙方平臺使用的簽名、加密方式和資料請求方式做了一個小結。主要提供MD5加密、SHA256withRSA簽名,以下程式碼包含了java和C#使用證照對引數簽名、加密。

一、證照籤名(C#)

    1、請求介面引數       
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("param1", "param1");
            dic.Add("param2", "param2");
            dic.Add("param3", "param3");
            string dicStr="************";//按照介面加密方式拼接引數得到要簽名的支付串
    2、對引數簽名(對應java的SHA256withRSA簽名方式有效)                   
            string sign = CaRsaEncrypt(dicStr);//證照加密
            dic.Add("sign", sign);
            //將字典轉為json格式字串            
            string jsonData = js.Serialize(dic);
            //通過post請求提交
            string url="請求介面url";       
            var result= PostGetJson<T>(url, jsonData);
    3、函式         
        /// <summary>
        /// 1、CA對字串加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string CaRsaEncrypt(string str)
        {
            //獲取商戶數字證照編號
            string path = HttpContext.Current.Server.MapPath("~/");
            //證照路徑
            string cert = path + "cert\\證照.p12";
            //呼叫證照           
            //SHA256WithRSA  
            X509Certificate2 privateCert = new X509Certificate2(cert, "證照密碼", X509KeyStorageFlags.Exportable);
            RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)privateCert.PrivateKey;
            // 獲取私鑰 
            RSACryptoServiceProvider privateKey1 = new RSACryptoServiceProvider();
            privateKey1.ImportParameters(privateKey.ExportParameters(true));
            byte[] data = Encoding.UTF8.GetBytes(str);
            byte[] signature = privateKey1.SignData(data, "SHA256");
            //對簽名密文進行Base64編碼 
            return Convert.ToBase64String(signature);
        }  
        /// <summary>
        /// 2、發起Post請求
        /// </summary>
        /// <typeparam name="T">返回資料型別(Json對應的實體)</typeparam>
        /// <param name="url">請求Url</param>
        /// <param name="cookieContainer">CookieContainer,如果不需要則設為null</param>
        /// <param name="fileStream">檔案流</param>
        /// <param name="encoding"></param>
        /// <param name="cer">證照,如果不需要則保留null</param>
        /// <param name="timeOut">代理請求超時時間(毫秒)</param>
        /// <param name="checkValidationResult">驗證伺服器證照回撥自動驗證</param>
        /// <returns></returns>
        public  T PostGetJson<T>(string url, string data)
        {
            string response = PostJsonSend(url, data);
            var result = GetResult<T>(response);
            return result;
        }
        /// <summary>
        /// 3、獲取Post結果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="returnText"></param>
        /// <returns></returns>
        public T GetResult<T>(string returnText)
        {
            if(string.IsNullOrEmpty(returnText))
            {
                return default(T);
            }
            T result = JsonConvert.DeserializeObject<T>(returnText); 
            return result;
        }
        /// <summary>
        /// 4、通過POST方式傳送資料
        /// </summary>
        /// <param name="url">目標URL</param>
        /// <param name="strData">Post資料</param>
        /// <returns></returns>
        public string PostJsonSend(string url, string strData)
        {
            string retString = string.Empty;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            //request.ContentType = "application/x-www-form-urlencoded";
            request.ContentType = "application/json; charset=UTF-8";
            byte[] bytes = Encoding.UTF8.GetBytes(strData);
            request.ContentLength = bytes.Length;
            request.AllowAutoRedirect = true;
            request.MaximumAutomaticRedirections = 5;
            request.Timeout = 20000;
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)";
            request.Proxy = null;
            bool IsIn = true;
            try
            {
                Stream myRequestStream = request.GetRequestStream();
                myRequestStream.Write(bytes, 0, bytes.Length);
                myRequestStream.Close();
            }
            catch (WebException wex)
            {
                retString = wex.Status.ToString();
                IsIn = false;
            }
            if (IsIn == false)
            {
                return "訪問超時.";
            }
            StreamReader myStreamReader = null;
            Stream myResponseStream = null;
            WebResponse wr = null;
            try
            {
                wr = request.GetResponse();
            }
            catch (WebException wex)
            {
                retString = wex.Message.ToString();
            }

            if (wr != null)
            {
                try
                {
                    HttpWebResponse response = (HttpWebResponse)wr;
                    myResponseStream = response.GetResponseStream();
                    if (myResponseStream != null)
                    {
                        myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
                        retString = myStreamReader.ReadToEnd();
                        if (retString == null)
                        {
                            retString = string.Empty;
                        }
                    }
                }
                catch (Exception ex)
                {
                    retString = ex.Message;
                }
                finally
                {
                    myStreamReader.Close();
                    myResponseStream.Close();
                }
            }
            return retString;
        }

二、MD5加密(C#)

    1、請求引數 
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("param1", "value1");
            dic.Add("param2", "value2");
            dic.Add("param3", "value3");
            //拼接引數
            string str = YouClass.DicToString(dic);//自定義方法對字典進行處理
            string encryptStr=EncryptByMD5(str);//加密

    2、加密方法
        /// <summary>
        /// MD5加密為32字元長度的16進位制字串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string EncryptByMD5(string input)
        {
            MD5 md5Hasher = MD5.Create();
            byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            //將每個位元組轉為16進位制
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString().ToUpper();
        }


三、對應的java證照籤名程式碼(java)


        InputStream resourceAsStream = Program.class.getClassLoader().getResourceAsStream("使用者證照.p12");
        String passwd = "證照密碼";
        String alias = "conname";
        String keyStoreType = "PKCS12";

        KeyCertInfo keyCertInfo = CryptoUtil.fileStreamToKeyCertInfo(resourceAsStream,passwd,keyStoreType,alias);
        BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();
        Signature signature = Signature.getInstance("SHA256withRSA",bouncyCastleProvider);
        //請求引數
        Map<String,String> translateResultData=new HashMap<>();
        translateResultData.put("param1","value1");
        translateResultData.put("param2","value2");
        translateResultData.put("param3","value3");

        //簽名
        String sign = SignatureUtil.sign(signature,content, (PrivateKey) keyCertInfo.getPrivateKey());

完結:到這裡文章就先告一段落,希望對自己和他人有點幫助。


相關文章