内容:Pfx证书,同时包含了公钥信息和私钥信息。

作用:保证了数据在传输过程中的安全性。

用法:私钥请求的数据进行签名,公钥对响应的数据进行验证签名。

代码:

第一步:将请求的数据进行ascii字典序,并添加Dictionary字典集合中。注意了(SortedDictionary<(Of <(TKey, TValue>)>) 和 SortedList<(Of <(TKey, TValue>)>) 都不是按照ascii排序的)正真的ascii字典序在下面:

配置pfx证书 java pfx证书如何使用_Data

配置pfx证书 java pfx证书如何使用_配置pfx证书 java_02

string[] keys = { "requestNo", "version", "transId", "agentId","cityId", "registerAddress", "regNo", "regMoney", "regAddress", "spIcp", "remarks", "cardNoCipher", "cardName", "cardBankNo"};//要请求数据变量名

Array.Sort(keys, string.CompareOrdinal);  //对请求数据变量名ascii排序

Dictionary<string, string> dictReq = new Dictionary<string, string>();//实例化字典集合对象
for (int i = 0; i <14; i++)    //遍历keys数组
{
  string formData = Request.Form[keys[i]];//获取请求数据变量名获取对应的表单内的值。
  if (!String.IsNullOrEmpty(formData)) //判断取出的值是否为空
  {
    dictReq.Add(keys[i], formData); //如果不为空,将变量名和值添加到dictReq字典集合中
  }
}

ascii字典序

 

第二步:将请求的数据进行签名。(证书存放路径:F:/API/cer/test.pdf 私钥密码 123456 接口请求路径:

配置pfx证书 java pfx证书如何使用_Data

配置pfx证书 java pfx证书如何使用_配置pfx证书 java_02

http://192.168.1.104:8010/interface)

string privateKeyUrl = "F:/API/cer/test.pdf";//私钥证书路径
string privateKeyPwd = "123456"//私钥证书密码
string signData = signature(dictReq, privateKeyUrl, privateKeyPwd);//请求数据签名

/// <summary>
/// 签名
/// </summary>
/// <param name="dictReq">签名数据</param>
/// <param name="privateKey">私钥</param>
/// <param name="privateKeyPwd">私钥密码</param>
/// <returns>返回post请求数据</returns>
public string signature(Dictionary<string, string> dictReq, string privateKey, string privateKeyPwd)
{
  string postData = ""; //url编码的post请求数据
  string signStr = ""; //待签名数据
  foreach (KeyValuePair<string, string> kvp in dictReq) //遍历键值对
  {
    if (kvp.Value == "") continue;//如果值为空,不参与签名
    if (kvp.Key != "signature") postData += kvp.Key + "=" + HttpUtility.UrlEncode(kvp.Value) + "&"; //拼接url编码的 
post请求数据
    if (kvp.Value != "") signStr += kvp.Key + "=" + kvp.Value + "&"; //拼接待签名数据
  }
  string signatureData = SignData(signStr.TrimEnd('&'),privateKey,privateKeyPwd);//签名
  return postData.TrimEnd('&') + "&signature=" + HttpUtility.UrlEncode(signatureData);返回post请求数据
}

/// <summary>
/// 将数据SHA1签名
/// </summary>
/// <param name="content">待签名字符串</param>
/// <param name="privateKey">私钥证书</param>
/// <param name="privateKeyPwd">私钥密码</param>
/// <returns>已签名base64编码数据</returns>
public string SignData(string content,string privateKey,string privateKeyPwd)
{
  X509Certificate2 cert = new X509Certificate2(privateKey,privateKeyPwd, X509KeyStorageFlags.MachineKeySet);//加载证 
书实体
  RSACryptoServiceProvider rsapri = (RSACryptoServiceProvider)cert.PrivateKey; //获取私钥证书
  RSAPKCS1SignatureFormatter f = new RSAPKCS1SignatureFormatter(rsapri);
  byte[] result;
  f.SetHashAlgorithm("SHA1");
  SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
  result = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(content));
  return System.Convert.ToBase64String(f.CreateSignature(result)).ToString();
}

签名

 

第三步:发送POST请求,获取返回结果(Post,Form)

配置pfx证书 java pfx证书如何使用_Data

配置pfx证书 java pfx证书如何使用_配置pfx证书 java_02

string postUrl = "http://192.168.1.104:8010/interface";//post请求地址

string resultData = TransSubmit(signData, postUrl);//发送POST请求,获取返回结果(Post,Form)

/// <summary>
/// 发送POST请求,获取返回结果(Post,Form)
/// </summary>
/// <param name="postData">请求数据</param>
/// <param name="postUrl">请求地址</param>
/// <returns>响应结果</returns>
public string TransSubmit(string postData,string postUrl)
{

  Encoding code = Encoding.GetEncoding("utf-8");
  byte[] bytesRequestData = code.GetBytes(postData);
  string str = "";

  WebRequest webRequest = WebRequest.Create(postUrl);
  HttpWebRequest myReq = webRequest as HttpWebRequest;
  myReq.Method = "post";
  myReq.ContentType = "application/x-www-form-urlencoded";
  myReq.ContentLength = bytesRequestData.Length;
  Stream requestStream = myReq.GetRequestStream();
  requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
  requestStream.Close();
  HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
  Stream myStream = HttpWResp.GetResponseStream();
  StreamReader Reader = new StreamReader(myStream);
  str = Reader.ReadToEnd();

  return str;

}

post请求

 

第四步:对响应的数据验证签名。

配置pfx证书 java pfx证书如何使用_Data

配置pfx证书 java pfx证书如何使用_配置pfx证书 java_02

string sign = GetUrlStrValue(resultData, "signature"); //截取响应结果的签名字符串

string sourceData = resultData.Substring(0, resultData.IndexOf("signature")-1); //响应的数据字符
string PublicKey = MyRsaUtil.GetPublicKey(privateKeyUrl,privateKeyPwd );//获取公钥证书
bool verifySign = MyRsaUtil.SignatureDeformatter(sourceData, sign, PublicKey);//公钥证书验证签名(为true,则验证签名成功 
。为false ,则验证签名失败)
if (verifySign)
{
  Response.Write("请求内容:" + signData);

  Response.Write("响应内容:"+resultData);

}
else
{
  Response.Write("验证签名失败");
}

/// <summary>
/// 截取路径字符串变量值
/// </summary>
/// <param name="sourceStr">路径字符串</param>
/// <param name="strof">变量名</param>
/// <returns>变量值</returns>
public string GetUrlStrValue(string sourceStr,string strof) { 
  sourceStr=sourceStr.Substring(sourceStr.IndexOf(strof+"="),sourceStr.Length-sourceStr.IndexOf(strof+"="));
  sourceStr = sourceStr + "&";
  sourceStr = sourceStr.Substring(sourceStr.IndexOf("=") + 1, sourceStr.IndexOf("&") - sourceStr.IndexOf("=") - 1);
  return sourceStr;
}

/// <summary>
/// 获取证书公钥
/// </summary>
/// <param name="pfxFileName">证书路径</param>
/// <param name="password">证书密码</param>
/// <returns>证书公钥</returns>
public string GetPublicKey(string pfxFileUrl, string password)
{
  X509Certificate2 _certificate = GetCertificateFromPfxFile(pfxFileName, password);
  return _certificate.PublicKey.Key.ToXmlString(false);
}

/// <summary>
/// 验证签名
/// </summary>
/// <param name="sourceData">响应的数据</param>
/// <param name="strEncryptString">签名</param>
/// <param name="publicKey">公钥</param>
/// <returns>true or false</returns>
public bool SignatureDeformatter(string sourceData, string sign,string publicKey)
{
  try
  {
    byte[] rgbHash = Encoding.UTF8.GetBytes(sourceData);
    RSACryptoServiceProvider key = new RSACryptoServiceProvider();
    key.FromXmlString(publicKey);
    bool result = key.VerifyData(rgbHash, "SHA1", Convert.FromBase64String(strEncryptString));
    return result;
  }
  catch
  {
    return false;
  }
}

验证签名