代码样例-数字签名
本文档包含生成api数字签名的代码样例,供开发者参考。
代码样例使用说明
- 代码样例不能直接运行,因为代码中的SecretId
o1fjh1re9o28876h7c08
、SecretKeyjd1gzm6ant2u7pojhbtl0bam0xpzsm1c
等信息都是虚构的,请替换成您自己的信息。 - 在下面的代码示例中,不同编程语言,甚至同一语言每次执行得到的 url 可能都有所不同,表现为参数的顺序不同,但这并不影响正确性。只要所有参数都存在,并且签名串计算正确即可。
- 使用代码样例过程中遇到问题请联系售后客服,我们会为您提供技术支持。
Python
Python数字签名实例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import time
import base64
import hashlib
import hmac
import requests
class Auth:
"""用于保存用户secretid、secretkey,以及计算签名的对象。"""
def __init__(self, secretid, secretkey):
self._secretid = secretid
self._secretkey = secretkey
@classmethod
def get_string_to_sign(cls, method, endpoint, params):
""" 生成签名原文字符串 """
s = method + endpoint.split('.com')[1] + '?'
query_str = '&'.join("%s=%s" % (k, params[k]) for k in sorted(params))
return s + query_str
def sign_str(self, raw_str, method=hashlib.sha1):
""" 生成签名串 """
try:
hmac_str = hmac.new(self.secretkey.encode('utf8'), raw_str.encode('utf8'), method).digest()
except UnicodeDecodeError as e:
hmac_str = hmac.new(self.secretkey.encode('utf8'), raw_str, method).digest()
return base64.b64encode(hmac_str)
@property
def secretid(self):
return self._secretid
@property
def secretkey(self):
return self._secretkey
def _get_base_res(method, endpoint, params):
"""处理基础请求,
若响应为json格式则返回请求结果dict
否则直接返回原格式
"""
try:
r = None
if method == "GET":
r = requests.get("https://" + endpoint, params=params)
elif method == "POST":
r = requests.post("https://" + endpoint, data=params)
if r.status_code != 200:
return 'HTTP Status Code: %s' % r.status_code
try:
return json.loads(r.content.decode('utf8'))
except ValueError as e: # 返回结果不是json格式, 直接返回
return r.content.decode('utf8')
except Exception as e:
print(str(e))
if __name__ == '__main__':
secretid = 'o1fjh1re9o28876h7c08'
secretkey = 'jd1gzm6ant2u7pojhbtl0bam0xpzsm1c'
method = 'GET' # 请求方式
endpoint = 'dps.kdlapi.com/api/getdpsvalidtime'
# 除signature外的所有参数都放入params
params = {
'secret_id': o1fjh1re9o28876h7c08,
'sign_type': 'hmacsha1',
'timestamp': int(time.time()),
'proxy': '27.42.139.229:2057',
}
auth = Auth(secretid, secretkey)
raw_str = auth.get_string_to_sign(method, endpoint, params)
params['signature'] = auth.sign_str(raw_str)
res = _get_base_res(method, endpoint, params)
print(res)
Java
Java数字签名实例
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
/**
* 用于保存用户secretid, secretkey, 以及计算签名的对象。
*/
public class Auth {
private final static String CHARSET = "UTF-8";
private String secretId;
private String secretKey;
public Auth(String secretId, String secretKey) {
this.secretId = secretId;
this.secretKey = secretKey;
}
public String sign(String s) throws Exception {
return sign(s, "HmacSHA1");
}
/**
* 生成签名字符串
*
* @param method 请求方式
* @param s 已经拼接好的原字符串
* @return Hmacsha1加密,并base64编码之后的原字符串。
* @throws Exception
*/
public String sign(String s, String method) throws Exception {
Mac mac = Mac.getInstance(method);
SecretKeySpec secretKeySpec = new SecretKeySpec(this.secretkey.getBytes(CHARSET), mac.getAlgorithm());
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(s.getBytes(CHARSET));
return DatatypeConverter.printBase64Binary(hash);
}
/**
* 生成原字符串
*
* @param endpoint 访问的地址
* @param method 请求方式
* @param params 其他参数
* @return 返回拼接好的原字符串
* @throws Exception
*/
public String getStringToSign(String method, String endpoint, TreeMap<String, Object> params) {
String s = method + endpoint.split(".com")[1] + "?";
StringBuilder s2s = new StringBuilder();
// 签名时要求对参数进行字典排序,此处用TreeMap保证顺序
for (String k : params.keySet()) {
s2s.append(k).append("=").append(params.get(k).toString()).append("&");
}
return s + s2s.toString().substring(0, s2s.length() - 1);
}
public String getsecretId() {
return this.secretId;
}
public String getsecretKey() {
return this.secretkey;
}
}
Golang
Golang数字签名实例
import (
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"sort"
"strings"
"github.com/kuaidaili/golang-sdk/api-sdk/kdl/utils"
)
// Auth 用于保存用户secretid、secretkey,以及计算签名
type Auth struct {
secretId string
secretKey string
}
// GetStringToSign 生成签名原文字符串
func (auth Auth) GetStringToSign(method string, endpoint string, params map[string]interface{}) string {
s := method + strings.Split(endpoint, ".com")[1] + "?"
var keys []string
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
var arr []string
for _, k := range keys {
arr = append(arr, k+"="+utils.TypeSwitcher(params[k]))
}
queryStr := strings.Join(arr, "&")
return s + queryStr
}
// SignStr 计算签名串
func (auth Auth) SignStr(rawStr string) string {
key := []byte(auth.secretKey)
hash := hmac.New(sha1.New, key)
hash.Write([]byte(rawStr))
sig := base64.StdEncoding.EncodeToString([]byte(string(hash.Sum(nil))))
return sig
}
NodeJS
NodeJS数字签名实例
global.crypto = require('crypto');
class Auth {
constructor(secretId, secretKey) {
this.secretId = secretId;
this.secretKey = secretKey;
}
get secret_id() {
return this.secretId;
}
get secret_key() {
return this.secretKey;
}
/**
* 生成签名原文字符串
*
* @method getStringToSign
* @for Auth
* @param {String} method 要访问的方式
* @param {String} ENDPOINT 地址
* @param {Array} params 不定长参数。就是携带的参数了。
* @return {String} 返回值原文字符串
*/
getStringToSign(method, ENDPOINT, params) {
let s = method + ENDPOINT.split('.com')[1] + '?';
let newParams = sortDict(params);
let queryStr = getQueryStr(newParams);
return s+queryStr;
}
/**
* 进行Hmacsha1加密
*
* @method signStr
* @for Auth
* @param {String} rawStr 原字符串
* @return {String} Hmacsha1加密,并base64编码之后的原字符串。
*/
signStr(rawStr, ) {
return crypto.createHmac('sha1',this.secret_key).update(rawStr).digest().toString('base64');
}
}
/**
* getQueryStr 将参数字典进行&拼接,构成formData格式
*
* @param {Array} dic 字典
* @return {String} 拼接好的字典
*/
function getQueryStr(dic){
let str = "";
let dicKey = Object.keys(dic);
for (let i = 0;i<dicKey.length;i++){
str += dicKey[i] + '=' + dic[dicKey[i]];
if(i!==dicKey.length-1){
str += '&';
}
}
return str;
}
/**
* sortDict 根据字典的key进行字典序排序
*
* @param {Array} dic 字典
* @return {Array} 新的已经排序好的字典
*/
function sortDict(dic){
let newDic = {};
let dickey = Object.keys(dic).sort();
for(let i = 0;i<dickey.length;i++){
newDic[dickey[i]] = dic[dickey[i]];
}
return newDic;
}
PHP
PHP数字签名实例
<?php
class Auth{
public $secretid;
public $secretkey;
function __construct($secretid, $secretkey){
$this -> secretid = $secretid;
$this -> secretkey = $secretkey;
}
/*
* 生成签名原文字符串
* @param string $method 请求方法
* @param string $endpoint
* @parms array $params
* @return string 签名原文字符串
*/
public function getStringToSign($method, $endpoint, $params){
$query_string = "";
ksort($params);
# 此处不应该使用http_build_query函数进行url编码, 而是用"&"符将各个参数连接
#$query_string = http_build_query($params);
foreach($params as $key => $value){
$query_string .= "$key=$value&";
}
$query_string = rtrim($query_string, "&");
list(, $string) = explode(".com", $endpoint);
$string = "$method"."$string"."?"."$query_string";
return $string;
}
/*
* 生成签名串
* @param string $raw_str 签名原文字符串
* @param string $method 加密方法,默认sha1
* @return string 签名串
*/
public function signStr($raw_str, $method="sha1"){
$hmac_str = hash_hmac($method, $raw_str, $this->secretkey, true);
$sign_str = base64_encode($hmac_str);
return $sign_str;
}
}
?>