# 签名机制
# 1 签名方法
签名时,您需要在项目详情页面查看目前项目的 accessKey 和 accessSecret。其中 accessKey 用于标识访问者身份;accessSecret 用于对称加密时的密钥,应严格保密,不能在空中传播;若泄露,可在项目详情里刷新。
- 签名方法
sign = sign_method(accessSecret, "accessKey{accessKey}timestamp{timestamp}random{randomStr}signMethod{signMethod}").HexToString() - 算法逻辑
randomStr 和时间戳防重复,timestamp 取当前时间戳,单位秒;sign_method 为签名算法;
待加密字符串需按指定顺序拼接;
将字符串和 secret 进行哈希,得到签名字符串,并转为十六进制小写字符串;
# 2 签名示例
一个用户的连接信息为:
accessKey: "GmXM0L69da381d51" accessSecret: "04d711bd2390ae4f605caff758df90e5" randomStr: "ae1786" signMethod: "hmacsha1" timestamp: "1631585734"
通过签名方法得到的新的签名:
sign = hmacsha1("04d711bd2390ae4f605caff758df90e5", "accessKeyGmXM0L69da381d51timestamp1631585734randomae1786signMethodhmacsha1") 计算得到的签名字符串为:
068baf6ed7a9f2c6df9f5d8f870b5add7460cf8b
请求头参数为:
access_key: GmXM0L69da381d51 sign: 068baf6ed7a9f2c6df9f5d8f870b5add7460cf8b sign_method: hmacsha1 timestamp: 1631585734 random_str: ae1786
# 3 代码示例
# 3.1 java
package example;
import java.security.Timestamp;
import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
public class SignUtils {
private static String accessKey = "GmXM0L69da381d51";
private static String accessSecret = "04d711bd2390ae4f605caff758df90e5";
private static String timestamp = "1631585734";
private static String randomStr = "ae1786";
private static String signMethod = "HmacSHA1";
public static void main(String[] args) throws Exception {
String sign = genHmacsha1Sign(accessKey, accessSecret);
System.out.println("sign: " + sign);
}
private static String genHmacsha1Sign(String accessKey, String secret) throws Exception {
String plainText = genSignString(accessKey, secret, timestamp, randomStr);
byte[] rawBytes = hmacsha1Sign(plainText);
return bytes2hex(rawBytes);
}
private static String genSignString(String accessKey, String secret, String timestamp, String randomStr) {
StringBuilder plainText = new StringBuilder();
plainText.append("accessKey").append(accessKey);
plainText.append("timestamp").append(timestamp);
plainText.append("random").append(randomStr);
plainText.append("signMethod").append("hmacsha1");
return plainText.toString();
}
private static byte[] hmacsha1Sign(String signString) throws Exception {
Mac mac = Mac.getInstance(signMethod);
SecretKeySpec keySpec = new SecretKeySpec(accessSecret.getBytes("utf8"), signMethod);
mac.init(keySpec);
return mac.doFinal(signString.getBytes("utf8"));
}
private static String bytes2hex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte aByte : bytes) {
result.append(String.format("%02x", aByte));
}
return result.toString();
}
} # 3.2 golang
package main
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"encoding/hex"
"errors"
"fmt"
"hash"
)
const (
accessKey = "GmXM0L69da381d51"
accessSecret = "04d711bd2390ae4f605caff758df90e5"
)
func main() {
signMethod := "hmacsha1"
timestamp := "1631585734"
randomStr := "ae1786"
sign, _ := authSign(accessKey, timestamp, randomStr, accessSecret, signMethod)
fmt.Println("signature: ", sign)
}
func authSign(accessKey, timestamp, randomStr, accessSecret, signMethod string) (string, error) {
src := ""
src = fmt.Sprintf("accessKey%stimestamp%srandom%ssignMethod%s", accessKey, timestamp, randomStr, signMethod)
var h hash.Hash
switch signMethod {
case "hmacsha1":
h = hmac.New(sha1.New, []byte(accessSecret))
case "hmacmd5":
h = hmac.New(md5.New, []byte(accessSecret))
default:
return "", errors.New("invalid sign method")
}
_, err := h.Write([]byte(src))
if err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
} # 3.3 python
import hmac,hashlib
access_key = "GmXM0L69da381d51"
access_secret = "04d711bd2390ae4f605caff758df90e5"
timestamp = "1631585734"
sign_method = "hmacsha1"
random_str = "ae1786"
def gen_sign_str(access_key, timestamp, sign_method, random_str):
plaintext = 'accessKey{}timestamp{}random{}signMethod{}'.format(access_key, timestamp, random_str, sign_method)
return plaintext
def sign(access_key, access_secret, timestamp, sign_method, random_str):
plaintext = gen_sign_str(access_key, timestamp, sign_method, random_str)
return hmac.new(bytes(access_secret, encoding="utf-8"), bytes(plaintext, encoding="utf-8"),hashlib.sha1).hexdigest()
if __name__ == '__main__':
signature = sign(access_key, access_secret, timestamp, sign_method, random_str)
print("sign: ", signature)