前言:公司项目对接了一个对数据保密性要求较高的java公司。api接口逻辑是这样的:他们提供 SHA1私钥 与 AES的秘钥。我们需要将 传递查询参数 通过SHA1 私钥加密再转换成 十六进制 字符串。传递查询参数 再通过 AES秘钥 加密转换成十六进制 字符串。
查询结果 也是一个十六进制字符串 需要转换成 byte 数组 再通过AES秘钥解密成 返回数据。
后面转换接口都需要十六进制字符串与byte数组 相互转换。这个具体得看开发者自己的接口要求了。我这边的项目要求 就是数据传递用十六进制字符串比较多。
1.十六进制字符串转换成byte数组
/// <summary>
/// 十六进制字符串换成byte数组转
/// </summary>
/// <param name="byteArray"></param>
/// <returns></returns>
private static byte[] HexStringToByteArray(
string s)
{
s = s.Replace(
" ",
"");
byte[] buffer =
new byte[s.Length /
2];
for (
int i =
0; i < s.Length; i +=
2)
{
buffer[i /
2] = (
byte)Convert.ToByte(s.Substring(i,
2),
16);
}
return buffer;
}
2.byte数组转换成十六进制字符串
/// <summary>
/// byte数组转换成十六进制字符串
/// </summary>
/// <param name="byteArray"></param>
/// <returns></returns>
private string bytesToHexStr(
byte[] byteArray)
{
StringBuilder sb =
new StringBuilder();
foreach (
byte b
in byteArray)
{
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
一、privateKey私钥转换成xml
.net的RSA仅仅支持 xml格式。第一步需要将java那边提供的SHA1私钥转换成xml格式
/// <summary>
/// 私钥=>十六进制字符串转换成xml
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
private static string RSAPrivateKeyJava2DotNet(
string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam =
(RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(HexStringToByteArray(privateKey));
return string.Format(
"<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}
二、c#SHA1加密
数据转换过程中 套有一个md5加密MD5Encrypt(都是按照乙方java的加密规则写的 我也觉得很繁琐)
/// <summary>
/// ASYMMETRY_ALGORITHM 加密类 SHA1
/// </summary>
/// <param name="signaturePrivateKey"></param>
/// <param name="signatureData">请求参数</param>
/// <returns></returns>
private string signature(
string signaturePrivateKey,
string signatureData)
{
RSACryptoServiceProvider rsa =
new RSACryptoServiceProvider();
var privateJavaKey =
signaturePrivateKey;
var privateCSharpKey =
RSAPrivateKeyJava2DotNet(privateJavaKey);
rsa.FromXmlString(privateCSharpKey);
var md5 =
MD5Encrypt(signatureData);
byte[] signatureBytes = rsa.SignData(Encoding.UTF8.GetBytes(md5),
"SHA1");
var hexStr =
bytesToHexStr(signatureBytes);
return hexStr;
}
MD5Encrypt
/// <summary>
/// 用MD5加密字符串
/// </summary>
/// <param name="jsonData">待加密的字符串</param>
/// <returns></returns>
public string MD5Encrypt(
string jsonData)
{
MD5CryptoServiceProvider md5Hasher =
new MD5CryptoServiceProvider();
byte[] hashedDataBytes;
hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding(
"gb2312").GetBytes(jsonData));
StringBuilder tmp =
new StringBuilder();
foreach (
byte i
in hashedDataBytes)
{
tmp.Append(i.ToString("x2"));
}
return tmp.ToString();
}
三、AES加密
/// <summary>
/// AES解密
/// </summary>
/// <param name="signaturePrivateKey"></param>
/// <param name="signatureData"></param>
/// <returns></returns>
private string decrypt(
string key,
string str)
{
if (
string.IsNullOrEmpty(str))
return null;
Byte[] toEncryptArray =
HexStringToByteArray(str);
RijndaelManaged rm =
new RijndaelManaged
{
Key =
HexStringToByteArray(key),
Mode =
CipherMode.ECB,
Padding =
PaddingMode.PKCS7
};
ICryptoTransform cTransform =
rm.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,
0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
四、请求接口获取返回数据
public objcet callIntegrateService()
{
var date =
DateTime.Now;
var startTime = Convert.ToDateTime(date.ToString(
"yyyy-MM-dd") +
" 00:00:00");
var endTime =
date;
var logstart =
ConvertDateTimeInt(startTime);//datetime转换成时间戳Unix
var logend =
ConvertDateTimeInt(endTime);
//var jsonData = "{}";
var jsonData =
"{ startTime: \"" + logstart +
"\",endTime:\"" + logend +
"\" }";
var url = base_url +
"/getProjectAttendanceDetail";
string signature =
getSignatrue(jsonData);
string encryptData =
encrypt(secretKey, jsonData);
var param =
"{ clientSerial:\""+ clientSerial +
"\",projectId:\"" + projectId +
"\",jsonData:\"" + encryptData +
"\",signature:\"" + signature +
"\" }";
var result=
webPost(url, param);
var objresult = JsonConvert.DeserializeObject<request>
(result);
var response =
objresult.response;
var data =
decrypt(secretKey, response);
var objdata =
JsonConvert.DeserializeObject(data);
return objdata;
}
五、解密返回数据
AES解密
/// <summary>
/// AES解密
/// </summary>
/// <param name="signaturePrivateKey"></param>
/// <param name="signatureData"></param>
/// <returns></returns>
private string decrypt(
string key,
string str)
{
if (
string.IsNullOrEmpty(str))
return null;
Byte[] toEncryptArray =
HexStringToByteArray(str);
RijndaelManaged rm =
new RijndaelManaged
{
Key =
HexStringToByteArray(key),
Mode =
CipherMode.ECB,
Padding =
PaddingMode.PKCS7
};
ICryptoTransform cTransform =
rm.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,
0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
转载于:https://www.cnblogs.com/wufanJY/p/10630408.html
相关资源:C# SHA1加密字符串