工作中,我们时刻都会和接口打交道,有的是调取他人的接口,有的是为他人提供接口,在这过程中肯定都离不开签名验证。
在设计签名验证的时候,一定要满足以下几点:
可变性:每次的签名必须是不一样的。
时效性:每次请求的时效性,过期作废。
唯一性:每次的签名是唯一的。
完整性:能够对传入数据进行验证,防止篡改。
下面主要分享一些工作中常用的加解密的方法。
常用验证
举例:/api/login?username=xxx&password=xxx&sign=xxx
发送方和接收方约定一个加密的盐值,进行生成签名。
示例代码:
//创建签名
private function _createSign()
{
$strSalt = '1scv6zfzSR1wLaWN';
$strVal = '';
if ($this->params) {
$params = $this->params;
ksort($params);
$strVal = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
}
return md5(md5($strSalt).md5($strVal));
}
//验证签名
if ($_GET['sign'] != $this->_createSign()) {
echo 'Invalid Sign.';
}
上面使用到了 MD5 方法,MD5 属于单向散列加密。
单向散列加密
定义
把任意长的输入串变化成固定长的输出串,并且由输出串难以得到输入串,这种方法称为单项散列加密。
常用算法
MD5
SHA
MAC
CRC
优点
以 MD5 为例。
方便存储:加密后都是固定大小(32位)的字符串,能够分配固定大小的空间存储。
损耗低:加密/加密对于性能的损耗微乎其微。
文件加密:只需要32位字符串就能对一个巨大的文件验证其完整性。
不可逆:大多数的情况下不可逆,具有良好的安全性。
缺点
存在暴力破解的可能性,最好通过加盐值的方式提高安全性。
应用场景
用于敏感数据,比如用户密码,请求参数,文件加密等。
推荐密码的存储方式
password_hash() 使用足够强度的单向散列算法创建密码的哈希(hash)。
示例代码:
//密码加密
$password = '123456';
$strPwdHash = password_hash($password, PASSWORD_DEFAULT);
//密码验证
if (password_verify($password, $strPwdHash)) {
//Success
} else {
//Fail
}
PHP 手册地址:
http://php.net/manual/zh/function.password-hash.php
对称加密
定义
同一个密钥可以同时用作数据的加密和解密,这种方法称为对称加密。
常用算法
DES
AES
AES 是 DES 的升级版,密钥长度更长,选择更多,也更灵活,安全性更高,速度更快。
优点
算法公开、计算量小、加密速度快、加密效率高。
缺点
发送方和接收方必须商定好密钥,然后使双方都能保存好密钥,密钥管理成为双方的负担。
应用场景
相对大一点的数据量或关键数据的加密。
AES
AES 加密类库在网上很容易找得到,请注意类库中的 mcrypt_encrypt 和 mcrypt_decrypt 方法!
在 PHP7.2 版本中已经被弃用了,在新版本中使用 openssl_encrypt 和 openssl_decrypt 两个方法。
示例代码(类库):
class Aes
{
/**
* var string $method 加解密方法
*/
protected $method;
/**
* var string $secret_key 加解密的密钥
*/
protected $secret_key;
/**
* var string $iv 加解密的向量
*/
protected $iv;
/**
* var int $options
*/
protected $options;