所谓非对称,就是使用公钥/私钥加密,然后用对应的私钥/公钥解密

1.配对的公钥,私钥:

//公钥(注意包括头(-----BEGIN PUBLIC KEY-----)尾(-----END PUBLIC KEY-----)标志)
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbdq5NjtUEkAQ6wucPuhC0aRvSMsaX3GrhkwsLLdWZnVNVpkJRw
yPFq9HJNuntRw7P9Sb3TkwrpN60x62kZ6qV8h1GoG4jIfofuVWPv1VzudAV6kWJWMl3sc
+DtV5q1dy1KQLb6e90cuOynzxVT3j+Fx7ZOzovmdTkEcoRiYWV1QIDAQAB
-----END PUBLIC KEY-----//私钥(注意包括头(-----BEGIN RSA PRIVATE KEY-----)尾(-----END RSA PRIVATE KEY-----)标志)
-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKBc0G8WmfydUuX6TnO5M3lSmNYqy8beEgBn24vWk6sWCZ2va+TRIWEew5dxmMXg5+N40a2XOJfyTxCALvzts+/J0q8efi2WIecPecWGNoDB8ZehGfzv3BQD5skk9sf1tL6ztU5tquPFajwmO85WR2pTFfk0CXgPEtLzPxntYfHpAgMBAAECgYB6DSo24qTgt3zYvOHpAhRDSrI4jun5uhtJY8Kdc/uAQ42eDl24EdOt75Q+N59nO/5CCzrLPEU+oJW8oVMh/mjr6gMv7QxhEr1iUrZmvAGTO2kB5sMgWfqPkiHeGddYWawcWGhAwQEJrrgGVldzaslY9FvWcmTjCjypEVvB7l1BgQJBAOJwB2RbRbI+z0d1M6DOawyu+J7JleMAQ42x9KyhiwYc/D0CZX0gkuyqGcwSh+c1CYjjdoRIh/531e1OZyBmRG0CQQC1TG68k+iXuz14+fgpHEttl2E3lQ6VfIzv+oaQHnRmmT92t2Eci70zkDFjVCGXxwQ279EokmP6RWfJG5Z1nV3tAkAZkHpVKzTQLeUq9SFyCzvsv6hUDQA+E56M1cWA4/AVLZqQrL+Wg+HylDW7Y3AyeztrV/rebm3kHdVqKEreTo11AkBPUou40nYXvQKeZbAgPJL79hnA+eSRnxcDAHfTop+HLFHKHV3N4Y38e4BAV1UDVT4Q00iOGc7Id4l7QijIePvZAkEA1OmJfbsaCx3T+4lZahzo8k7NzP5BS6izPVAVk8O3LHo3TggJZMa69Nc+8O82ZXOiOSt7bSONaST54ejjN8yhtg==
-----END RSA PRIVATE KEY-----

2.判断openssl扩展是否安装

 extension_loaded('openssl') or die('PHP加密需要openssl扩展支持');

3.判断公钥和私钥是否可用

//私钥文件路径
$this->privateKey = file_get_contents(dirname(__FILE__) .'libraries/YCPAY/account/rsa_private_key.pem');//公钥文件路径
$this->publicKey = file_get_contents(dirname(__FILE__) . 'libraries/YCPAY/account/rsa_public_key.pem');  /**
* 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
*/
$privateKey = openssl_pkey_get_private($this->privateKey);/**
* 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
*/
$publicKey = openssl_pkey_get_public($this->publicKey);($privateKey) or die('密钥不可用');
($publicKey) or die('公钥不可用');

4.公钥加密

由于openssl_public_encrypt()加密对加密串有字符限制(117字节),所有需要分段加密(每段32个字符,加密后拼接起来)

    define("BAOFOO_ENCRYPT_LEN", 32);    // 公钥加密function encryptedByPublicKey($data_content){$publicKey = openssl_pkey_get_public($this->publicKey);$encrypted = "";$totalLen = strlen($data_content);$encryptPos = 0;while ($encryptPos < $totalLen) {
//            openssl_public_encrypt(substr($data_content, $encryptPos, BAOFOO_ENCRYPT_LEN), $encryptData, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);openssl_public_encrypt(substr($data_content, $encryptPos, BAOFOO_ENCRYPT_LEN), $encryptData, $publicKey);
//            $encrypted .= bin2hex($encryptData);$encrypted .= base64_encode($encryptData);$encryptPos += BAOFOO_ENCRYPT_LEN;}return $encrypted;}

5.私钥解密

由于openssl_private_decrypt()加密对加密串有字符限制(128字节),所有需要分段解密后拼接起来

    // 私钥解密function encryptedByPrivateKey($data_content){$privateKey = openssl_pkey_get_private($this->privateKey);$crypto = '';$data_content = base64_decode($data_content);foreach (str_split($data_content, 128) as $chunk) {openssl_private_decrypt($chunk, $decryptData, $privateKey);$crypto .= $decryptData;}return $crypto;}

6.完整代码如下,仅供参考

define("BAOFOO_ENCRYPT_LEN", 32);//CI框架
class YcPay extends MY_Controller
{private $privateKey;private $publicKey;private $merIdNum;private $merKey;private $url;public function __construct(){parent::__construct();//正式环境$this->privateKey = file_get_contents(APPPATH . 'libraries/YCPAY/account/rsa_private_key.pem');$this->publicKey = file_get_contents(APPPATH . 'libraries/YCPAY/account/rsa_public_key.pem');$this->merIdNum = 'dc0020663';$this->merKey = '5446042869aaf86d22c5d19189f21956';$this->url = 'https://mis.ixianhe.cn/action/exp/';}// 公钥加密function encryptedByPublicKey($data_content){
//        $data_content = base64_encode($data_content);$publicKey = openssl_pkey_get_public($this->publicKey);$encrypted = "";$totalLen = strlen($data_content);$encryptPos = 0;while ($encryptPos < $totalLen) {
//            openssl_public_encrypt(substr($data_content, $encryptPos, BAOFOO_ENCRYPT_LEN), $encryptData, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);openssl_public_encrypt(substr($data_content, $encryptPos, BAOFOO_ENCRYPT_LEN), $encryptData, $publicKey);
//            $encrypted .= bin2hex($encryptData);$encrypted .= base64_encode($encryptData);$encryptPos += BAOFOO_ENCRYPT_LEN;}return $encrypted;}// 私钥解密function encryptedByPrivateKey($data_content){$privateKey = openssl_pkey_get_private($this->privateKey);$crypto = '';$data_content = base64_decode($data_content);foreach (str_split($data_content, 128) as $chunk) {openssl_private_decrypt($chunk, $decryptData, $privateKey);$crypto .= $decryptData;}return $crypto;}//检测密钥+加密public function rsa_pass($params, $api_method, $is_big){extension_loaded('openssl') or die('php需要openssl扩展支持');/*** 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false*/$privateKey = openssl_pkey_get_private($this->privateKey);/*** 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false*/$publicKey = openssl_pkey_get_public($this->publicKey);
//        ($privateKey) or die('密钥不可用');
//        ($publicKey) or die('公钥不可用');if (empty($privateKey)) {$param_back = ['resCode' => '9999','resMsg' => '密钥不可用',];$this->log($param_back, 'rsa_pass', $is_big, '错误报文:');echo json_encode($param_back, JSON_UNESCAPED_UNICODE);exit;}if (empty($publicKey)) {$param_back = ['resCode' => '9999','resMsg' => '公钥不可用',];$this->log($param_back, $api_method, $is_big, '错误报文:');echo json_encode($param_back, JSON_UNESCAPED_UNICODE);exit;}/*** 原数据*/$originalData = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
//        var_dump(strlen($originalData));die;//用公钥加密$encryptData = $this->encryptedByPublicKey($originalData);return $encryptData;}/*** 签名 + post请求* @param array $params 请求参数* @param string $method 第三方方法名* @param string $api_method 接口名* @param string $is_big 通道别名* @param string $bankcardNo 银行卡号* @return mixed*/public function sign_post($params, $method, $api_method, $is_big, $bankcardNo = ''){$this->log($params, $api_method, $is_big, '业务数据:', $bankcardNo);//公钥加密(RSA/ECB/PKCS1Padding)$encryptData = $this->rsa_pass($params, $api_method, $is_big);$merSign = "merIdNum=" . $this->merIdNum . "&encryptData=" . $encryptData . "&merKey=" . $this->merKey;//公共参数$request_param = ['merVersion' => '3.0','merIdNum' => $this->merIdNum,'requestMethod' => 'exp.' . $method,'merSign' => md5($merSign),'encryptData' => $encryptData,];$requestUrl = $this->url . $method;$this->log($requestUrl, $api_method, $is_big, '请求url:');$this->log($request_param, $api_method, $is_big, '请求报文:');$request_param = json_encode($request_param, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);$res = $this->curl($requestUrl, $request_param);$this->log($res, $api_method, $is_big, '响应报文:');//        $third_array = [
//            'userStatus'=>'E0000',
//            'userMsg'=>'绑卡申请成功',
//            'encryptData'=>'lVa1eNpFP5V6ImaFbk2s2mu7ptY8cHc+ANrI3o38ZTdeR+OfZsOA1BeWD8vDacBl7eFA7GgTA6OM2mzIuwlT4wkgm8IpNshRwtKHwTAri0c4HsZ+2qTfZJjybiB36eJ3CsiPntlae7wsMcNx9hxlDvcs19D77mufEVhTWYQYcHc=',
//            'merIdNum'=>'dc0020450',
//            'merSign'=>'79d52ca53003c3c7b73916dac313c38a',
//        ];
//        $this->log($third_array, $api_method, $is_big, '响应报文:');$third_array = json_decode($res, true);if ($third_array['userStatus'] == 'E0000' && isset($third_array['encryptData'])) {//私钥解密$third_res = $this->encryptedByPrivateKey($third_array['encryptData']);$this->log($third_res, $api_method, $is_big, '解密报文:');//处理返回$third_array['data'] = json_decode($third_res);//解密报文:{"orderDesc":"交易成功","orderStatus":"SUCCESS","userLinkId":"YCDA9CA_257919_162701706280078"}} else {//失败响应的两种情况//【2021-07-22 15:56:23】响应报文:{"userStatus":"E0000","userMsg":"结算请求已受理","encryptData":"Rfyvdj3HUOtGzMAbP4Jh4EQpd9VXDr7BLQD5fRwz+TOvCwI6EubNv4MdXCWuRN1zm9C17bvt27jx1I67ceVHhFW/vpqNEBG5eTmqJjXP6PJrJwiyf03yrK3EUOXf7wgpdAH5NW3PrywrWLmt/lC2hNvUf02iQ0gXRxN3Ka6X9k4a1QfjSJRXYTXdUlVshDWx+Y1gMKRvLTrOW4IzaJpyYpd/KXI7ahEAYqWCqEruPhRIUV9N+z+lECHIeG0Ml/sC7/AdBTs4oT+LgMNGsxCH5n1RoFj4EhqcVCrrrYW5O900sdrn78xURWo3yvkL2up6vDMV9fmViV2udwAVC+wD6Q==","merIdNum":"dc0020663","merSign":"342e58237f3e68213f23815410585a9b"}//【2021-07-22 15:56:23】解密报文:{"orderDesc":"商户手续费金额超过了最大手续费限制","orderStatus":"FAIL","userLinkId":"YCDA9CA_162990_162694058243001"}//------------------------//【2021-07-23 11:01:03】响应报文:{"userStatus":"E0002","userMsg":"用户余额不足"}//这样处理了之后前端才不会出错 $third_array['data'] = ["orderDesc" => $third_array['userMsg'],"orderStatus" => "FAIL",//订单状态 SUCCESS 交易成功  FAIL交易失败  PROCESSING  交易处理中];}$third_json = json_encode($third_array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);return $third_json;}//接口post请求public function curl($url = '', $data = ''){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);if (!empty($data)) {curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);}curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_TIMEOUT, 30); //超时时间30秒curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$headers = ['Content-type: application/json'];curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$output = curl_exec($ch);curl_close($ch);return $output;}/*** 日志记录* @param $data /内容* @param $method /方法名* @param $bankcardNo /银行卡号* @param string $is_big /通道别名* @param string $title /标题*/public function Log($data, $method, $is_big, $title, $bankcardNo = ''){$str = is_array($data) ? json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $data;if (empty($bankcardNo)) {$content = '【' . date('Y-m-d H:i:s') . '】' . $title . $str . PHP_EOL;} else {$content = ' bankcardNo:' . $bankcardNo . '【' . date('Y-m-d H:i:s') . '】' . $title . $str . PHP_EOL;}$path = APPPATH . "../PAYLOG/$is_big/$method/";if (!is_dir($path)) { //判断目录是否存在 不存在就创建mkdir($path, 0777, true);}file_put_contents($path . date("Y-m-d") . '.txt', $content, FILE_APPEND);//换行分割file_put_contents($path . date("Y-m-d") . '.txt', '------------------------' . PHP_EOL, FILE_APPEND);}
}

对应的私钥加密和公钥加密函数

openssl_private_encrypt($data,$encrypted,$this->privateKey);//私钥加密

openssl_public_decrypt($encrypted,$decrypted,$this->publicKey);//私钥加密的内容通过公钥可用解密出来

参考博文:https://blog.csdn.net/qq_27517377/article/details/79047021

PHP非对称加密:RSA (RSA/ECB/PKCS1Padding)+base64_encode/bin2hex加密相关推荐

  1. Go语言的DES加密(CBC模式, ECB模式) ---- 与java加密互通(转)

    问题场景: 业务需要对接接口, 采用DES加密方式加密, 于是google一下go的DES加密方式, go的DES的默认隐藏了ECB模式, 因为go认为ECB不安全, 所以不建议使用,就隐藏了, 然而 ...

  2. rsa/ecb/pkcs1padding php,PHPJAVA RSA/ECB/PKCS1Padding 加密解密

    PHP代码: $privateKeyFilePath = '-----BEGIN RSA PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwgg ...

  3. python rsa加密长度_python RSA加密最新(RSA/ECB/PKCS1Padding)

    遇到一个 java 的RSA/ECB/PKCS1Padding 加密 要改成python的 网上搜一堆不靠谱的,没办法只能自己动手写一份了 中间遇到一个ERROR: OverflowError: 45 ...

  4. 非对称加密之RSA算法

    非对称加密之RSA算法 1. RSA算法简述 2. 模型分析 3.代码实现 3.1 算法实现 3.2 测试代码 3.3 测试结果 4. 算法实现分析 5. 数据分段处理 该系列文章列表 1.网络及数据 ...

  5. Python代码实现MD5、AES对称加密和RSA非对称加密以及OpenSSl实践

    1.MD5加密算法 1.1 MD5加密的特点 不可逆运算 对不同的数据加密的结果是定长的32位和16位字符(不管文件多大都一样) 对相同的数据加密,得到的结果是一样的(也就是复制). 抗修改性 :信息 ...

  6. [crypto]-52-python3中rsa(签名验签加密解密)aes(ecb cbc ctr)hmac的使用,以及unittest测试用

    环境: 在ubuntu14.04下,记得安装:sudo pip3 install pycrypto 代码示例1: =========================== import base64 f ...

  7. 对称加密、非对称加密、RSA、消息摘要、数字签名、数字证书与 HTTPS 简介

    文章目录 1.加密算法简介 1.1 对称加密(Symmetric Key Algorithms) 1.2 非对称加密(Asymmetric Key Algorithms) 1.3 非对称加密 RSA ...

  8. 非对称加密下RSA在Java的简明教程

    引言 在现实世界中,每个人都有自己的密码.在各种系统中都有各类加密和解密的需求. 本文将详细介绍一下RSA的前身后世,应用场景和在Java中的实现,从理论到实践,一步到位,触手可用. 非对称加密与对称 ...

  9. 非对称算法之一RSA加密解密的java demo

    RSA加密算法,著名的非对称加密算法之一. 1,私钥加密,公钥解密例子(通常用在数字证书签名上). package rsa;import org.apache.commons.codec.binary ...

最新文章

  1. 基于单片机的超市储物柜设计_657【毕设课设】基于单片机智能存柜储物柜存储柜系统设计...
  2. 基因组序列及注释数据下载
  3. (转)iOS开发资源:推送通知相关开源项目--PushSharp、APNS-PHP以及Pyapns等
  4. golang中的http conn实现分析
  5. Javascript----input事件实现动态监听textarea内容变化
  6. EJB3.0 Timer
  7. python新手入门代码-新手必看:手把手教你入门 Python
  8. [解决]RESTEASY003215: could not find writer for content-type text/html type: java.lang.String
  9. 信号与系统学习难点(一)群时延与相频特性
  10. Linux环境下利用perl脚本批量筛选VCF文件指定样本
  11. SpringBoot从入门到精通教程(三十)- 支付宝企业支付集成(五分钟集成)
  12. python数学公式识别_python用re正则表达式实现数学公式计算
  13. Cocos Creator 获得手机陀螺仪(Gyrometer)数据
  14. 如何单步调试存储过程
  15. mysql导出数据到文件
  16. 快手,存在的优势都有哪些???
  17. 灵魂拷问!Mysql和Redis数据同步该怎么做?请查收
  18. 怎么最快地复制一张表?
  19. Gitee+PicGo上传图片失败404 - {“status“:“404“,“error“:“Not Found“}
  20. 智能电视 屏幕测试软件,详解如何使用液晶电视测试软件

热门文章

  1. malloc,colloc,realloc内存分配,动态库,静态库的生成与调用
  2. MULE ESB功能介绍
  3. html text width,HTML5 Text Canvas rotate in case text width is larger than maximum width allowed
  4. NodeJs 在window中安装使用
  5. 目标检测中召回率(Recall),精确率(Precision),平均正确率(Average_precision(AP) ),交除并(Intersection-over-Union(IoU))
  6. Dropout_layer.cpp(防止过拟合)
  7. 补码(为什么按位取反再加一):告诉你一个其实很简单的问题
  8. 基于Walle的多渠道快速打包自动脚本
  9. Java之控制反转和依赖注入
  10. 2016及以后的自动化测试趋势 -《测试技术六月刊》