RSA+PHP 非对称加密解密
目录
- 生成密钥
- 业务场景
- PHP 服务端
- 微信客户端
- 浏览器客户端
生成密钥
# 生成私钥文件
openssl genrsa -out rsa_private_key.pem 1024
# 生成公钥文件
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
# 生成私钥文件 two
openssl genrsa -out rsa_private_key_two.pem 1024
# 生成公钥文件 two
openssl rsa -in rsa_private_key_two.pem -pubout -out rsa_public_key_two.pem
业务场景
为了安全起见采用
(服务端:rsa_public_key_two
加密,rsa_private_key
解密,客户端:rsa_private_key_two
解密,rsa_public_key
解密)
双秘钥进行加密解密,如果实行不通可以多次试验。
实际上
S(two 公钥加密,one 私钥解密)
C(two 私钥解密,one 公钥加密)
// 当然还有其他的加密解密方法,我这里略过...
PHP 服务端
// 先配置一下证书,可以在config.php 追加或在 extra 目录新建一个 rsa.php 配置文件,视个人情况而定。
'rsa' => [
// 秘钥 one
'private_key' => file_get_contents(ROOT_PATH. 'rsa_private_key.pem'),
'public_key' => file_get_contents(ROOT_PATH. 'rsa_public_key.pem'),
// 秘钥 two
'private_key_two' => file_get_contents(ROOT_PATH. 'rsa_private_key_two.pem'),
'public_key_two' => file_get_contents(ROOT_PATH. 'rsa_public_key_two.pem'),
]
// 加密函数使用到了 OpenSSL 扩展,在服务端需要先安装并开启 OpenSSL 扩展,默认使用的是 PKCS1 填充模式。
/**
* @Author(作者): YALE
* @DateTime(开发创建时间): 2022/3/1
* @LastTime(最后修改时间): 2022/3/1
* @param $str
* @Return(返回值): string
* @FunctionName(方法名称): encryptData
* @Remarks(备注): RSA 加密
*/
function encryptData($str) {
$result = '';
$chunks = str_split($str, 117);
foreach ($chunks as $value) {
openssl_public_encrypt($value, $crypted, config('rsa.public_key_two'));
$result .= base64_encode($crypted);
}
return $result;
}
/**
* @Author(作者): YALE
* @DateTime(开发创建时间): 2022/3/1
* @LastTime(最后修改时间): 2022/3/1
* @param $data
* @Return(返回值): string
* @FunctionName(方法名称): decryptData
* @Remarks(备注): RSA 解密
*/
function decryptData($data) {
$result = '';
$chunks = str_split($data, 172);
foreach ($chunks as $value) {
openssl_private_decrypt(base64_decode($value), $decrypted, config('rsa.private_key'));
$result .= $decrypted;
}
return $result;
}
通用:jsencrypt
微信客户端
// 根据情况使用 全局引入 或 局部引入
import JSEncrypt from '@/static/jsencrypt';
// 示例为全局引入,配置 main.js
Vue.prototype.jsencrypt = new JSEncrypt();
// 公钥解密
Vue.prototype.public_key = `-----BEGIN PUBLIC KEY-----
********************************************
-----END PUBLIC KEY-----`;
// 私钥加密
Vue.prototype.private_key = `-----BEGIN RSA PRIVATE KEY-----
********************************************
-----END RSA PRIVATE KEY-----`;
// 加密解密方法
// 设置公钥
this.jsencrypt.setPublicKey(this.public_key);
// 加密
var string = this.jsencrypt.encryptLong(JSON.stringify({name:'yale', age: 18}))
console.log(string);
// 设置私钥
this.jsencrypt.setPrivateKey(this.private_key);
// 解密
console.log(this.jsencrypt.decryptLong(string));
浏览器客户端
由于使用的是双秘钥的方式所以客户端不能自己加密解密
其他平台暂时没有涉及到,遇到后再补充了