Abel'Blog

我干了什么?究竟拿了时间换了什么?

0%

HMAC

简介

wiki-说明

Java

Java-HmacSHA256

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public static String encode(String key, String data) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);

return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

public static void main(String [] args) throws Exception {
System.out.println(encode("key", "The quick brown fox jumps over the lazy dog"));
}

// 签名一个请求
void createSignature(String accessKey, String secretKey, String method, String host,
String uri, UrlParamsBuilder builder) {
StringBuilder sb = new StringBuilder(1024);

if (accessKey == null || "".equals(accessKey) || secretKey == null || "".equals(secretKey)) {
throw new MyApiException(MyApiException.KEY_MISSING,
"API key and secret key are required");
}

sb.append(method.toUpperCase()).append('\n')
.append(host.toLowerCase()).append('\n')
.append(uri).append('\n');

builder.putToUrl(accessKeyId, accessKey) // 将访问key存入html的head中
.putToUrl(signatureVersion, signatureVersionValue)
.putToUrl(signatureMethod, signatureMethodValue)
.putToUrl(timestamp, gmtNow());

sb.append(builder.buildSignature());
Mac hmacSha256;
try {
hmacSha256 = Mac.getInstance(signatureMethodValue);
SecretKeySpec secKey = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8),
signatureMethodValue); // 构造加密key
hmacSha256.init(secKey); // 填充hmacSha256
} catch (NoSuchAlgorithmException e) {
throw new MyApiException(MyApiException.RUNTIME_ERROR,
"[Signature] No such algorithm: " + e.getMessage());
} catch (InvalidKeyException e) {
throw new MyApiException(MyApiException.RUNTIME_ERROR,
"[Signature] Invalid key: " + e.getMessage());
}
String payload = sb.toString();
byte[] hash = hmacSha256.doFinal(payload.getBytes(StandardCharsets.UTF_8)); // 将原始数据使用 mac SH256 算出hash

String actualSign = Base64.getEncoder().encodeToString(hash);

builder.putToUrl(signature, actualSign); // 将签名写入的头

}

示例

1
2
3
4
HMAC_MD5("key", "The quick brown fox jumps over the lazy dog")    = 80070713463e7749b90c2dc24911e275
HMAC_SHA1("key", "The quick brown fox jumps over the lazy dog") = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC_SHA256("key", "The quick brown fox jumps over the lazy dog") = f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC_SHA256("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dog", "message") = 5597b93a2843078cbb0c920ae41dfe20f1685e10c67e423c11ab91adfc319d12

linux

1
2
[linux]$ echo -n "symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000&timestamp=1499827319559" | openssl dgst -sha256 -hmac "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
(stdin)= c8db56825ae71d6d79447849e617115f4a920fa2acdcab2b053c4b2838bd6b71