基于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());
完结:到这里文章就先告一段落,希望对自己和他人有点帮助。