1, 生成公钥和私钥
要应用 RSA 算法, 必须先生成公钥和私钥, 公钥和私钥的生成可以借助 openssl 工具.
也可以用在线生成公私钥.(网站: http://web.chacuo.net/netrsakeypair) 密钥位数: 1024 位, 密钥格式: PKCS#1 示例生成如下:
公钥的内容:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7
eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4
6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET
- uqkpR4bN5afMZNmGbQIDAQAB
- -----END PUBLIC KEY-----
私钥的内容:
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV
6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05
YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB
AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD
SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U
Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i
ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV
Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t
jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C
XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h
LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV
- Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX
- emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==
- -----END RSA PRIVATE KEY-----
常规: 公钥和私钥生成好了之后, 私钥自己保存, 将公钥交给第三方即可.
2,php 的 RSA 加密解密
在做加密解密之前, 首先要确保 php 已经开启了 openssl 拓展, 可以通过 phpinfo() 函数进行查看.
通常情况下, 有以下两种情形:
通过公钥加密, 通过私钥解密;
通过私钥加密, 通过公钥解密;
示例解释: 支付宝的业务场景属于第二种情形.
业务方 向 支付宝 发送支付请求, 将 sign 参数通过自己的私钥加密过后发送到支付宝的接口; (业务方签名 sign 属于第二种情形: 加密.)
支付宝 向 业务方 发送支付回调结果, 将 sign 参数通过自己的私钥加密过后发送到业务方的 notify 接口;(解密支付宝回调 sign 验签 属于第二种情形: 解密 可俗称验签.)
注: 支付宝使用的加密函数是 openssl_sign, 之后的校验可以使用 openssl_verify 函数进行校验.
- // 公私钥加密示例代码:
- $content = '待加密的字符串, 自己替换';
- // 示例直接取私钥内容, 自己替换
- // 注意: priKey 是一串连续字符, 如果存在空格需要去除
- $priKey = 'MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV';
- $priKey .='6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05';
- $priKey .='YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB';
- $priKey .='AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD';
- $priKey .='SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U';
- $priKey .='Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i';
- $priKey .='ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV';
- $priKey .='Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t';
- $priKey .='jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C';
- $priKey .='XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h';
- $priKey .='LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV';
- $priKey .='Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX';
- $priKey .='emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==';
- echo createSign($content,$priKey);
- /**
- * 创建 RSA 加密签名
- * @param string $content
- * @param string $priKey
- * @return mixed
- */
- function createSign($content, $priKey){
- // 转换成 PrivateKey 格式
- $priKey = convertPrivateKey($priKey);
- // 获取私钥内容
- $openssl_private_key = openssl_get_privatekey($priKey);
- // 对数据进行 PKCS1 签名 签名还有 MD5,SHA,RMD 根据自己实例代码修改
- //openssl_sign($content, $signature, $openssl_private_key, OPENSSL_ALGO_MD5);
- @openssl_private_encrypt($content, $signature, $openssl_private_key, OPENSSL_PKCS1_PADDING);
- // 释放资源
- @openssl_free_key($openssl_private_key);
- // 对签名进行 Base64 编码, 变为可读的字符串
- $sign = base64_encode($signature);
- if (empty($sign)) {
- return false;
- }
- return $sign;
- }
- /**
- * 转换 PrivateKey
- * @param string $priKey
- * @return string
- */
- function convertPrivateKey($priKey) {
- // 判断是否传入私钥内容
- $private_key_string = !empty($priKey) ? $priKey : '';
- //64 位换行私钥内容
- $private_key_string = chunk_split($private_key_string, 64, "\r\n");
- // 私钥头部
- $private_key_header = "-----BEGIN RSA PRIVATE KEY-----\r\n";
- // 私钥尾部
- $private_key_footer = "-----END RSA PRIVATE KEY-----";
- // 完整私钥拼接
- $private_key_string = $private_key_header.$private_key_string.$private_key_footer;
- return $private_key_string;
- }
获取 sign 签名如下: "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU="
- // 公私钥解密示例代码:
- $sign = "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU=";
- // 示例直接取公钥内容, 自己替换
- // 注意: publickey, 如果存在空格需要去除
- $publickey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7';
- $publickey .= 'eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4';
- $publickey .='6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET';
- $publickey .='uqkpR4bN5afMZNmGbQIDAQAB';
- echo checkSign($sign,$publickey);
- /**
- * RSA 解密 (验签)
- * @param string $sign
- * @param string $publickey
- * @return 0 or 1
- */
- function checkSign($sign, $publickey){
- // 转换成 PublicKey 格式
- $publickey = convertPublicKey($publickey);
- // 获取公钥钥内容
- $openssl_public_key = @openssl_get_publickey($publickey);
- // 对数据进行解密
- //$result = @openssl_verify($content,base64_decode($sign), $openssl_public_key,OPENSSL_ALGO_MD5);
- $result = openssl_public_decrypt(base64_decode($sign), $decrypted, $openssl_public_key,OPENSSL_PKCS1_PADDING);
- // 释放资源
- @openssl_free_key($openssl_public_key);
- return $result;
- }
- /**
- * 转换 PublicKey
- * @param string $publicKey
- * @return string
- */
- function convertPublicKey($publicKey) {
- // 判断是否传入公钥内容
- $public_key_string = !empty($publicKey) ? $publicKey : '';
- //64 位换行公钥钥内容
- $public_key_string = chunk_split($public_key_string, 64, "\r\n");
- // 公钥头部
- $public_key_header = "-----BEGIN PUBLIC KEY-----\r\n";
- // 公钥尾部
- $public_key_footer = "-----END PUBLIC KEY-----";
- // 完整公钥拼接
- $public_key_string = $public_key_header.$public_key_string.$public_key_footer;
- return $public_key_string;
- }
验证返回值是: 1 验签成功 0 验签失败
posted on 2018-06-04 13:44 echo 曦 阅读 (...) 评论 (...) 编辑 收藏
来源: https://www.cnblogs.com/cxx8181602/p/9132946.html