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 相关文章推荐
在PHP3中实现SESSION的功能(三)
Oct 09 PHP
关于时间计算的结总
Dec 06 PHP
php MYSQL 数据备份类
Jun 19 PHP
php 删除记录同时删除图片文件的实现代码
May 12 PHP
php关于array_multisort多维数组排序的使用说明
Jan 04 PHP
PHP 使用header函数设置HTTP头的示例解析 表头
Jun 17 PHP
php_imagick实现图片剪切、旋转、锐化、减色或增加特效的方法
Dec 15 PHP
php带抄送和密件抄送的邮件发送方法
Mar 20 PHP
php支持中文字符串分割的函数
May 28 PHP
使用PHPCMS搭建wap手机网站
Sep 20 PHP
PHP实现求解最长公共子串问题的方法
Nov 17 PHP
PHP实现的策略模式示例
Mar 20 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
echo(),print(),print_r()之间的区别?
2006/11/19 PHP
实用函数2
2007/11/08 PHP
如何用PHP做到页面注册审核
2017/03/02 PHP
ThinkPHP开发--使用七牛云储存
2017/09/14 PHP
多浏览器支持的右下角浮动窗口
2010/04/01 Javascript
基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果)
2011/09/28 Javascript
jQuery学习笔记 操作jQuery对象 文档处理
2012/09/19 Javascript
简介JavaScript中toTimeString()方法的使用
2015/06/12 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
JavaScript+Html5实现按钮复制文字到剪切板功能(手机网页兼容)
2017/03/30 Javascript
详解webpack 多入口配置
2017/06/16 Javascript
vue结合axios与后端进行ajax交互的方法
2018/07/06 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
react 应用多入口配置及实践总结
2018/10/17 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
express启用https使用小记
2019/05/21 Javascript
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
Vue SPA 初次进入加载动画实现代码
2019/11/14 Javascript
Vue Render函数创建DOM节点代码实例
2020/07/08 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
[05:03]显微镜下的DOTA2第十期——Ti3豪之超神幽鬼
2014/06/23 DOTA
python队列原理及实现方法示例
2019/11/27 Python
Python设计密码强度校验程序
2020/07/30 Python
新加坡第一大健康与美容零售商:屈臣氏新加坡(Watsons Singapore)
2020/12/11 全球购物
数据库基础的一些面试题
2012/02/25 面试题
理货员的岗位职责
2013/11/23 职场文书
国庆节标语大全
2014/10/08 职场文书
领导干部作风建设总结
2014/10/23 职场文书
幼儿园欢迎词范文
2015/01/26 职场文书
紧急通知
2015/04/17 职场文书
小学运动会加油词
2015/07/18 职场文书
节约用水广告语60条
2019/11/14 职场文书
Python中Permission denied的解决方案
2021/04/02 Python
MYSQL优化之数据表碎片整理详解
2022/04/03 MySQL