HmacSHA256
因为C#的byte是无符号类型,取值范围为0~255,java的byte类型是有符号类型,取值为-128~127,当ComputeHash获取到hash值后,需要判断byte是否小于等于127,如果满足条件则取当前值,否则就使用当前值(byte)减去256
C# 实现
csharp
/// <summary>
/// hmacSHA256加密实现
/// </summary>
/// <returns>The token.</returns>
/// <param name="secret">Secret.</param>
/// <param name="signKey">加密参数</param>
// ReSharper disable once InconsistentNaming
public static string HmacSHA256Encrypt(string secret, string signKey)
{
using (var mac = new HMACSHA256(Encoding.UTF8.GetBytes(signKey)))
{
mac.Initialize();
var hash = mac.ComputeHash(Encoding.UTF8.GetBytes(secret));
var sb = new sbyte[hash.Length];
for (var i = 0; i < hash.Length; i++)
{
// 语言差异导致结果不同 此处做处理
sb[i] = hash[i] <= 127 ? (sbyte)hash[i] : (sbyte)(hash[i] - 256);
}
var unsignedByteArray = (byte[])(Array)sb;
// 直接base64编码
//return Convert.ToBase64String(unsignedByteArray);
// 先转16进制 再base64编码
return Convert.ToBase64String(Encoding.UTF8.GetBytes(ToHex(unsignedByteArray)));
}
}
转 Hex 字符
csharp
/// <summary>
/// 字节数组转换为Hex字符串
/// </summary>
/// <param name="data"></param>
/// <param name="toLowerCase"></param>
/// <returns></returns>
public static string ToHex(byte[] data, bool toLowerCase = true)
{
var hex = BitConverter.ToString(data).Replace("-", string.Empty);
return toLowerCase ? hex.ToLower() : hex.ToUpper();
}
Java 实现
java
public static void main(String[] args) {
try {
// url 为调用相关接口的地址
String url = "www.domain.com";
String signSource = "POST".concat(url);
String timeStamp = String.valueOf(System.currentTimeMillis());
String secretId = "165161616165";
String stringToSign = secretId + timeStamp + signSource;
String secretKey ="!secretKey";
//HmacSHA256算法
Mac mac;
mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256"));
byte[] signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8"));
String hexStr = Hex.encodeHexString(signatureBytes);
String signature = Base64.encodeBase64String(hexStr.getBytes());
//Postman调用的header
System.out.println("sign: "+ signature);
System.out.println("timeStamp: " + timeStamp);
System.out.println("secretId: " + secretId);
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}