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 相关文章推荐
攻克CakePHP系列二 表单数据显示
Oct 22 PHP
在PHP中实现Javascript的escape()函数代码
Aug 08 PHP
php的ajax框架xajax入门与试用介绍
Dec 19 PHP
php Ubb代码编辑器函数代码
Jul 05 PHP
Windows中使用计划任务自动执行PHP程序实例
May 09 PHP
php简单获取文件扩展名的方法
Mar 24 PHP
php fseek函数读取大文件两种方法
Oct 12 PHP
yii2利用自带UploadedFile实现上传图片的示例
Feb 16 PHP
php操作access数据库的方法详解
Feb 22 PHP
ThinkPHP下表单令牌错误与解决方法分析
May 20 PHP
如何通过View::first使用Laravel Blade的动态模板详解
Sep 21 PHP
PHP与Perl之间知识点区别整理
Mar 19 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
东芝TOSHIBA RP-F11电路分析
2021/03/02 无线电
详解PHP内置访问资源的超时时间 time_out file_get_contents read_file
2013/06/03 PHP
php读取纯真ip数据库使用示例
2014/01/26 PHP
yii操作cookie实例简介
2014/07/09 PHP
学习ExtJS Panel常用方法
2009/10/07 Javascript
js/jQuery对象互转(快速操作dom元素)
2013/02/04 Javascript
jQuery实现可拖动的浮动层完整代码
2013/05/27 Javascript
jQuery学习笔记之jQuery构建函数的7种方法
2014/06/03 Javascript
轻松创建nodejs服务器(10):处理上传图片
2014/12/18 NodeJs
js库Modernizr的介绍和使用
2015/05/07 Javascript
轻量级javascript 框架Backbone使用指南
2015/07/24 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
利用vue.js插入dom节点的方法
2017/03/15 Javascript
微信小程序canvas写字板效果及实例
2017/06/15 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
微信小程序用户信息encryptedData详解
2018/08/24 Javascript
Vue.js数字输入框组件使用方法详解
2019/10/19 Javascript
element中的$confirm的使用
2020/04/26 Javascript
Python中方法链的使用方法
2016/02/23 Python
python实现多层感知器
2019/01/18 Python
详解Python数据可视化编程 - 词云生成并保存(jieba+WordCloud)
2019/03/26 Python
Python图像处理PIL各模块详细介绍(推荐)
2019/07/17 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
python3.x中安装web.py步骤方法
2020/06/23 Python
基于Python的自媒体小助手---登录页面的实现代码
2020/06/29 Python
CSS3制作翻转效果_动力节点Java学院整理
2017/07/11 HTML / CSS
VSCode 自定义html5模板的实现
2019/12/05 HTML / CSS
通往英国高街的商店橱窗:Down Your High Street
2020/07/19 全球购物
大学生求职自荐信
2013/12/12 职场文书
心得体会怎么写
2013/12/30 职场文书
春季防火方案
2014/05/10 职场文书
党的群众路线教育实践活动个人剖析材料
2014/10/07 职场文书
社区班子个人对照检查材料思想汇报
2014/10/07 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle
python使用torch随机初始化参数
2022/03/22 Python