统一平台和客户端的通讯采用JSON格式,通讯双方发送和接收数据都必须进行签名和验签,签名串保存在sign变量名下,签名算法描述如下:
加签算法:
将请求参数以参数名按字典序排序(升序,即A在首位),然后将参数值连接成字符串,接着使用通信密码对其进行AES加密,最后对加密结果进行sha256运算得出签名串
签名算法代码示例:
(PHP语言版)
/**
* 得到签名串
*
* @param array $order 发送到统一平台的参数信息数组
* @param null $key 加密密钥 一般不用传递
*
* @return string
*/
public function getSign($order = [], $key = NULL) {
unset($order['sign']);
ksort($order);
if (empty($key)) {
$key = $this->config->get('key'); //取回通讯密码
}
$str = implode('', $order); //这里用空连接符也意在避免参数存在但无值时签名不同的问题
$str = (new AES())->aesEncrypt($str, $key);
$sign = hash('sha256', $str);
return $sign;
}
验证签名如下:
//这里假设$jsonArr是响应json解码后的数组
//其必须是完整的,否则验证不会成功,因为签名串保护所有数据
if (!isset($jsonArr['sign']) || $jsonArr['sign'] != $this->getSign($jsonArr)) {
return false; //响应签名错误
}
当签名验证错误时,必须拒绝后续处理
AES加密算法如下:
<?php
/**
* AES加密类, 加密算法aes-128-cbc,分组长度128比特 加密模式为CBC
*/
class AES{
/**
* 使用AES加密算法加密文本
*
* @param $plainText String 明文 不限制位数 即便是空字符""都行
* @param $key String 对称密钥 不限制位数 即便是空字符""都行,但建议在16个字符
*
* @return string base64转码后的密文
*/
public function aesEncrypt($plainText, $key) {
$iv = substr(hash('sha256', $key), 0, 16); //产生初始化加密向量
return openssl_encrypt($plainText, 'aes-128-cbc', $key, 0, $iv);
}
/**
* AES解密
*
* @param $cipherText String 密文
* @param $key String 对称密钥
*
* @return string
*/
public function aesDecrypt($cipherText, $key) {
$iv = substr(hash('sha256', $key), 0, 16);
return openssl_decrypt($cipherText, 'aes-128-cbc', $key, 0, $iv);
}
}
以上加密算法结果示例:
明文:$str='未来很美科技';
密码:$key='admin';
密文:‘CUasyTzO1iEQg9+iZJvE+6O+B+x1JeR34LeXikbnnYg=’
注意:以上不带引号
即:
$str='未来很美科技';
$key='admin';
echo $str = (new AES())->aesEncrypt($str, $key);
输出: CUasyTzO1iEQg9+iZJvE+6O+B+x1JeR34LeXikbnnYg=