| 算法名称 | 标准名称 | 备注 |
|---|---|---|
| RSA2 | SHA256WithRSA | 强制要求RSA密钥的长度至少为2048 |
| RSA | SHA1WithRSA | 对RSA密钥的长度不限制,推荐使用2048位以上 |
RSA2 比 RSA 有更强的安全能力。
蚂蚁金服,新浪微博 都在使用 RSA2 算法。
创建公钥和私钥:
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
执行上面命令,会生成private_key.pem和public_key.pem两个文件。
示例代码(类库):
class Rsa2
{
private static $PRIVATE_KEY = 'private_key.pem 内容';
private static $PUBLIC_KEY = 'public_key.pem 内容';
/**
* 获取私钥
* @return bool|resource
*/
private static function getPrivateKey()
{
$privateKey = self::$PRIVATE_KEY;
return openssl_pkey_get_private($privateKey);
}
/**
* 获取公钥
* @return bool|resource
*/
private static function getPublicKey()
{
$publicKey = self::$PUBLIC_KEY;
return openssl_pkey_get_public($publicKey);
}
/**
* 私钥加密
* @param string $data
* @return null|string
*/
public static function privateEncrypt($data = '')
{
if (!is_string($data)) {
return null;
}
return openssl_private_encrypt($data,$encrypted,self::getPrivateKey()) ? base64_encode($encrypted) : null;
}
/**
* 公钥加密
* @param string $data
* @return null|string
*/
public static function publicEncrypt($data = '')
{
if (!is_string($data)) {
return null;
}
return openssl_public_encrypt($data,$encrypted,self::getPublicKey()) ? base64_encode($encrypted) : null;
}
/**
* 私钥解密
* @param string $encrypted
* @return null
*/
public static function privateDecrypt($encrypted = '')
{
if (!is_string($encrypted)) {
return null;
}
return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey())) ? $decrypted : null;
}
/**
* 公钥解密
* @param string $encrypted
* @return null
*/
public static function publicDecrypt($encrypted = '')
{
if (!is_string($encrypted)) {
return null;
}
return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey())) ? $decrypted : null;
}
/**
* 创建签名
* @param string $data 数据
* @return null|string
*/
public function createSign($data = '')
{
if (!is_string($data)) {
return null;
}
return openssl_sign($data, $sign, self::getPrivateKey(), OPENSSL_ALGO_SHA256) ? base64_encode($sign) : null;
}
/**
* 验证签名
* @param string $data 数据
* @param string $sign 签名
* @return bool
*/
public function verifySign($data = '', $sign = '')
{
if (!is_string($sign) || !is_string($sign)) {
return false;
}
return (bool)openssl_verify($data, base64_decode($sign), self::getPublicKey(), OPENSSL_ALGO_SHA256);
}
}
示例代码:
$rsa2 = new Rsa2();
$privateEncrypt = $rsa2->privateEncrypt('锄禾日当午');
echo '私钥加密后:'.$privateEncrypt.'br>';
$publicDecrypt = $rsa2->publicDecrypt($privateEncrypt);
echo '公钥解密后:'.$publicDecrypt.'br>';
$publicEncrypt = $rsa2->publicEncrypt('锄禾日当午');
echo '公钥加密后:'.$publicEncrypt.'br>';
$privateDecrypt = $rsa2->privateDecrypt($publicEncrypt);
echo '私钥解密后:'.$privateDecrypt.'br>';
$sign = $rsa2->createSign('锄禾日当午');
echo '生成签名:'.$privateEncrypt.'br>';
$status = $rsa2->verifySign('锄禾日当午', $sign);
echo '验证签名:'.($status ? '成功' : '失败') ;
运行结果:
部分数据截图如下:

JS-RSA
JSEncrypt:用于执行OpenSSL RSA加密、解密和密钥生成的Javascript库。
Git源:https://github.com/travist/jsencrypt
应用场景:
我们在做 WEB 的登录功能时一般是通过 Form 提交或 Ajax 方式提交到服务器进行验证的。
为了防止抓包,登录密码肯定要先进行一次加密(RSA),再提交到服务器进行验证。
一些大公司都在使用,比如淘宝、京东、新浪 等。
示例代码就不提供了,Git上提供的代码是非常完善的。
这些加密技术,能够达到安全加密效果的前提是密钥的保密性。
实际工作中,不同环境的密钥都应该不同(开发环境、预发布环境、正式环境)。
那么,应该如何安全保存密钥呢?
环境变量
将密钥设置到环境变量中,每次从环境变量中加载。
配置中心
将密钥存放到配置中心,统一进行管理。
密钥过期策略
设置密钥有效期,比如一个月进行重置一次。
在这里希望大佬提供新的思路 ~
Postman
一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome插件。
这个不用多介绍,大家肯定都使用过。
SocketLog
Git源:https://github.com/luofei614/SocketLog
解决的痛点:
SocketLog,可以解决以上问题,它通过WebSocket将调试日志输出到浏览器的console中。
使用方法
接口开发完毕,需要给请求方提供接口文档,文档的编写现在大部分都使用Markdown格式。
也有一些开源的系统,可以下载并安装到自己的服务器上。
也有一些在线的系统,可以在线使用同时也支持离线导出。
根据自己的情况,选择适合自己的文档平台吧。
常用的接口文档平台:
一、在 HTTP 和 RPC 的选择上,可能会有一些疑问,RPC框架配置比较复杂,明明用HTTP能实现为什么要选择RPC?
下面简单的介绍下 HTTP 与 RPC 的区别。
传输协议:
HTTP 也是 RPC 实现的一种方式。
性能消耗:
推荐一个像 JSON ,但比 JSON 传输更快占用更少的新型序列化类库MessagePack。
官网地址:https://msgpack.org/
还有一些服务治理、负载均衡配置的区别。
使用场景:
比如浏览器接口、APP接口、第三方接口,推荐使用 HTTP。
比如集团内部的服务调用,推荐使用 RPC。
RPC 比 HTTP 性能消耗低,传输效率高,服务治理也方便。
推荐使用的 RPC 框架:Thrift。
二、动态令牌
简单介绍下几种动态令牌,感兴趣的可以深入了解下。
OTP:One-Time Password 一次性密码。
HOTP:HMAC-based One-Time Password 基于HMAC算法加密的一次性密码。
TOTP:Time-based One-Time Password 基于时间戳算法的一次性密码。
使用场景:
本文讲了设计签名验证需要满足的一些条件:可变性、时效性、唯一性、完整性。
还讲了一些加密方法:单向散列加密、对称加密、非对称加密,同时分析了各种加密方法的优缺点,大家可以根据自己的业务特点进行自由选择。
提供了 Aes、Rsa 相关代码示例。
分享了可以编写接口文档的在线系统。
分享了开发过程中使用的接口调试工具。
扩展中分析了 HTTP 和 RPC 的区别,动态令牌的介绍等。
以上就是详解PHP接口签名验证的详细内容,更多关于PHP接口签名验证的资料请关注脚本之家其它相关文章!
上一篇:PHP屏蔽错误的方法总结