最近接一个项目,需要调用对方接口生成 token 但只提供了 node 版,源代码如下
//https://blog.zhengxianjun.com/2015/05/javascript-crypto-js/
npm install crypto-js
var CryptoJS = require('crypto-js')
calSignature = function (toSign, key) {
var hash, hex, signed;
hash = CryptoJS.HmacSHA1(toSign, key);
hex = hash.toString(CryptoJS.enc.Hex);
signed = base64.encodeBase64(hex);
return signed;
};
var hmacSHA1 = CryptoJS.HmacSHA1("Message", "Secret Passphrase").toString(CryptoJS.enc.Hex);
console.log(hmacSHA1) ;//e90f713295ea4cc06c92c9248696ffafc5d01faf
也可以在线测试 https://blog.zhengxianjun.com/online-tool/hash/
var str = '123456';
CryptoJS.MD5(str);
var str = '123456';
var password = 'password';
// Hmac 相关调用前都增加了 Hmac
CryptoJS.HmacMD5(str, password);
CryptoJS.HmacRIPEMD160(str, password);
CryptoJS.HmacSHA1(str, password);
但是我们的项目是基于 PHP 于是有了
$sign = base64_encode(hash_hmac('sha1', $sign, $key));
果然 PHP 是最好的语言,一句话搞定。
另外说到请求对方接口的问题,对方要求传递一个 json 参数过去,比如
$url = 'xxxxx.com';
$data = ['limit' => ['start' => 0, 'end' => 5]];
$res = curlGet($url.'/api/?'.json_encode($data);
结果提示 fail Malformed HTTP request line
但是 python get 没问题
res = requests.get(url, params=data, headers=headers)
于是对参数再进行一次 base64
$res =curlGet($url.'/api/?'.base64_encode(json_encode($data));
但对方有时候接受的参数 base64 解析出错
>>> s='eyJsaW1pdCI6eyJzdGFydCI6MCwiZW5kIjo1fSwidGFibGVfbmFtZSI6Im9ubGluZV91dl9hY
2NvdW50X2lkXzFob3VyX2FuYWx5c2lzX2RhdGEiLCJmaWx0ZXJfYXJncyI6eyJ2ZmlkIjoiMTQiLCJ0a
W1lc3RhbXBfMWhvdXIiOiIyMDE4LTAxLTA1IDIwOjA0OjI2In0sImJpel9kZXMwMSI6MCwib3JkZXJfY
nkiOiJ0aW1lc3RhbXBfMWhvdXIifQ'
>>> base64.b64decode(s)
Traceback (most recent call last):
File "", line 1, in
File "d:\python27\lib\base64.py", line 76, in b64decode
raise TypeError(msg)
TypeError: Incorrect padding
>>> base64.b64decode(s+'===')
'{"limit":{"start":0,"end":5}'
于是有了如下处理
def decode_base64(data):
missing_padding = len(data) % 4
if missing_padding != 0:
data += b'='* (4 - missing_padding)
return base64.decodestring(data)
传递时也改成 安全 base64
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
function urlsafe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}
$res =curlGet($url.'/api/?'.urlsafe_b64encode(json_encode($data));