php的RSA加密解密算法原理与用法分析


Posted in PHP onJanuary 23, 2020

本文实例讲述了php的RSA加密解密算法原理与用法。分享给大家供大家参考,具体如下:

最近因为工作的需要,要倒腾支付宝支付相关的知识,因为支付宝应用了RSA加密机制,个人对此并不了解,所以在这里写下一篇总结。

1、生成公钥和私钥

要应用RSA算法,必须先生成公钥和私钥,公钥和私钥的生成可以借助openssl工具。

本次测验是在windows下进行的,可以到以下的地址下载windows安装包:http://gnuwin32.sourceforge.net/packages/openssl.htm,安装过程不再赘述。

安装过后,进入到安装目录的bin目录下,执行如下命令:

openssl.exe     // 进入OpenSSL程序
genrsa -out rsa_private_key.pem 1024 //生成私钥,执行成功后可以在当前目录下看到生成了rsa_private_key.pem文件
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt  //如果你使用的java,需要将私钥转换成PKCS8格式
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem //生成公钥,执行成功后可以在当前目录下看到生成rsa_public_key.pem文件

公钥rsa_public_key.pem的内容:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc5nSC6mHl9bmM6L8n7Sq1+Ft6
VF8LcU3jst8RIy7WqXXd5XZomc0cJLxVz3Vc0vgUKKJyP6q2ozDOCFgCp7Q9InFg
ngtNVLEJ1+Nm0+snUDbYbnrfW8wwSPG0jPQ73CgMxOdv+IGhir6mEITbdEh+ZsVc
GRd0OvKYIg+Itgk3/QIDAQAB
-----END PUBLIC KEY-----

私钥rsa_private_key.pem的内容:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDD4KA0yU7EG7ZA32OAVDHlwXf9LYywXGn7Ma9LffnFL57cpYoQ
Wf0Oz8FE9/UnjFOeHs2XjDrhe+uqVtYX/9Vi/znJgP9D7hpTo2NJHM/AUykD+itl
cie2Tu+sjJQi0JFVcpc3D0ooTBhng35406CucRaOn/a52mxQnGtA4AmsSwIDAQAB
AoGAG25nwTy39SrUWT1vl9cyrbRsc15fp4sppG4O2Imp4v2KR+g+749KqzpZHKmF
AabbRveVXzXaQR2zoUVL8kx3u4hqY4M/S1AcOxNPIJKB703XxA1yf2Ta2CvLsWTm
tsDWRW1WudF18yOZf3q7aoyMhpBUMlmhH4mvIYWOPFj0zaECQQD4A11Q8sfpOcIK
fMz5jJymLMZ9P8gxNbafwjxTdTXht/MUprEAePslP3AeyKBMJNYGs04/lOQzksp+
ZG6j7/XzAkEAyi9zj8EaPlleAil8mB5wDWiibQ/Z92nMLSUmH5FoO013dvumBI8c
CcP1/go2sj3H4RQEWycr360yTubNkkHOSQJAcRRPos3fOkZ8Y329k3Z6IgY+RfMj
2tQLvVG5YbAKbi0J5vuNrpJ6p+QBwfdlpvIQp6NvZOwFFEK0kuZFz/dj4wJBALyc
cZCMUoARfEpGC24ZDuzjTIqzO+G7d3Yx7pOKYRLZXHXJogEkw8I0ZXmca5PxYFIP
C1VBgINEHedPFjy3WMkCQEh3FG0xDpUFXETct5L1whT8lsN0EK3ZmcfDePcbKuHW
iE5pbNn7ytpVT+jiT3+FVEZVSZCiW0lDnyd86Ppos5g=
-----END RSA PRIVATE KEY-----

公钥和私钥生成好了之后,私钥自己保存,将公钥交给第三方即可。

2、php的RSA加密解密

在做加密解密之前,首先要确保php已经开启了openssl拓展,可以通过phpinfo()函数进行查看。

通常情况下,有以下两种情形:

①通过公钥加密,通过私钥解密;

②通过私钥加密,通过公钥解密;

支付宝的业务场景属于第二种情形:

  1. 业务方支付宝发送支付请求,将sign参数通过自己的私钥加密过后发送到支付宝的接口;
  2. 支付宝方向业务方发送支付结果,将sign参数通过自己的私钥加密过后发送到业务方的notify接口;

下面就以支付宝的业务逻辑为例,实现以下第二种加解密:

加密:

$data = "我是待加密的字符串";
echo sign($data, 'rsa_private_key.pem');
 /* 签名 */
function sign($data, $rsaPrivateKey) {
   /* 获取私钥PEM文件内容,$rsaPrivateKey是指向私钥PEM文件的路径 */
   $priKey = file_get_contents($rsaPrivateKey);
   /* 从PEM文件中提取私钥 */
   $res = openssl_get_privatekey($priKey);
   /* 对数据进行签名 */
   //openssl_sign($data, $sign, $res);
   openssl_private_encrypt($data, $sign, $res);
   /* 释放资源 */
   openssl_free_key($res);
   /* 对签名进行Base64编码,变为可读的字符串 */
   $sign = base64_encode($sign);
   return $sign;
 }

执行后得到如下字符串:

geNTbwabOYT1l2TIkaxgxnCZDop8pynyNtMNbYATtmyyOlxgJhm363ufeHbNboIhc3Pzi7kVrWPPkFsNUiGnS4mATzAcf0woJVC+26g5j19yQqb00Fr+XVipEVyN0sn9/uhlot6m6qj7h5adaREvsY/30jTld6kDkkQF8k3Eg+Y=

解密:

$data = "geNTbwabOYT1l2TIkaxgxnCZDop8pynyNtMNbYATtmyyOlxgJhm363ufeHbNboIhc3Pzi7kVrWPPkFsNUiGnS4mATzAcf0woJVC+26g5j19yQqb00Fr+XVipEVyN0sn9/uhlot6m6qj7h5adaREvsY/30jTld6kDkkQF8k3Eg+Y=";
echo decrypt($data, 'rsa_public_key.pem');
function decrypt($data, $rsaPublicKey) {
   /* 获取公钥PEM文件内容,$rsaPublicKey是指向公钥PEM文件的路径 */
   $pubKey = file_get_contents($rsaPublicKey);
   /* 从PEM文件中提取公钥 */
   $res = openssl_get_publickey($pubKey);
   /* 对数据进行解密 */
   openssl_public_decrypt(base64_decode($data), $decrypted, $res);
   /* 释放资源 */
   openssl_free_key($res);
   return $decrypted;
 }

第一种情形与第二种情形类似,在此不在赘述。

注:支付宝使用的加密函数是openssl_sign,之后的校验可以使用openssl_verify函数进行校验。

PHP 相关文章推荐
探讨:如何编写PHP扩展
Jun 13 PHP
解析php中memcache的应用
Jun 18 PHP
ThinkPHP3.1新特性之多层MVC的支持
Jun 19 PHP
ThinkPHP实现一键清除缓存方法
Jun 26 PHP
ThinkPHP整合百度Ueditor图文教程
Oct 21 PHP
PHP内存缓存Memcached类实例
Dec 08 PHP
php读取mssql的ntext字段返回值为空的解决方法
Dec 30 PHP
PHP、Java des加密解密实例
Apr 27 PHP
php采集神器cURL使用方法详解
Feb 19 PHP
基于PHPexecl类生成复杂的报表表头示例
Oct 14 PHP
Ubuntu 16.04下安装PHP 7过程详解
Mar 28 PHP
解决thinkphp6(tp6)在状态码500下不报错,或者显示错误“Malformed UTF-8 characters”的问题
Apr 01 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
Jan 23 #PHP
PHP实现一个按钮点击上传多个图片操作示例
Jan 23 #PHP
利用PHP内置SERVER开启web服务(本地开发使用)
Jan 22 #PHP
PHP读取文件,解决中文乱码UTF-8的方法分析
Jan 22 #PHP
php经典趣味算法实例代码
Jan 21 #PHP
php利用ZipArchive类操作文件的实例
Jan 21 #PHP
Laravel 手动开关 Eloquent 修改器的操作方法
Dec 30 #PHP
You might like
php环境无法上传文件的解决方法
2014/04/30 PHP
浅谈Laravel中的一个后期静态绑定
2017/08/11 PHP
IE与FireFox的兼容性问题分析
2007/04/22 Javascript
JavaScript constructor和instanceof,JSOO中的一对欢喜冤家
2009/05/25 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
2010/11/21 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
2011/04/08 Javascript
jQuery统计上传文件大小的方法
2015/01/24 Javascript
JavaScript的jQuery库中ready方法的学习教程
2015/08/14 Javascript
jQuery实现淡入淡出二级下拉导航菜单的方法
2015/08/28 Javascript
jQuery插件EasyUI实现Layout框架页面中弹出窗体到最顶层效果(穿越iframe)
2016/08/05 Javascript
JS图片预加载插件详解
2017/06/21 Javascript
详解vue 不同环境配置不同的打包命令
2019/04/07 Javascript
开发Node CLI构建微信小程序脚手架的示例
2020/03/27 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
Python中创建字典的几种方法总结(推荐)
2017/04/27 Python
Python 判断 有向图 是否有环的实例讲解
2018/02/01 Python
Flask框架各种常见装饰器示例
2018/07/17 Python
python requests 测试代理ip是否生效
2018/07/25 Python
通过实例解析Python return运行原理
2020/03/04 Python
Mysql数据库反向生成Django里面的models指令方式
2020/05/18 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Python urllib3软件包的使用说明
2020/11/18 Python
Python爬取酷狗MP3音频的步骤
2021/02/26 Python
css3中的calc函数浅析
2018/07/10 HTML / CSS
美国时尚女装在线:Missguided
2016/12/03 全球购物
印度最大的时尚购物网站:Myntra
2018/09/13 全球购物
会计学财务管理专业个人的自我评价
2013/10/19 职场文书
商务英语专业毕业生自荐信
2013/11/05 职场文书
职业技术学校毕业生推荐信
2013/12/03 职场文书
甜品蛋糕店创业计划书范文
2014/02/06 职场文书
物业总经理岗位职责
2014/02/28 职场文书
食品业务员岗位职责
2014/03/18 职场文书
防灾减灾活动总结
2014/08/30 职场文书
2014高中生入党思想汇报范文
2014/09/13 职场文书
详解Spring事件发布与监听机制
2021/06/30 Java/Android
Python实现为PDF去除水印的示例代码
2022/04/03 Python