IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP RSA 加解密 对接Java -> 正文阅读

[PHP知识库]PHP RSA 加解密 对接Java

近期对接一项目,对方是Java,用到了rsa的加解密以及签名。熬了一天才解决。。。

rsa的加解密需要用到OpenSSL的公钥私钥,在我上一篇的文章又说到,不懂得可以去看。

先上代码,然后再说这次开发中踩的坑::

一、RSA 加解密类

<?php
namespace util;
use Exception;
class RSA
{
    const PKCS1 = 'PKCS#1';
    const PKCS8 = 'PKCS#8';

    private $rsa_public;
    private $rsa_private;
    private $key_format;
    private $padding;

    public function __construct($rsa_public, $rsa_private, $key_format = self::PKCS8, $padding = OPENSSL_PKCS1_PADDING)
    {
        $this->rsa_public = $rsa_public;
        $this->rsa_private = $rsa_private;
        $this->key_format = $key_format;
        $this->padding = $padding;
    }
    public function sign($str)
    {
        openssl_sign($str, $sign,  $this->getPrivateKey());
       return base64_encode($sign);
    }

    // 加密
    public function encrypt($content)
    {
        $crypto = '';
        $pu_key = $this->getPublicKey();
        foreach (str_split($content, 117) as $chunk) {
            openssl_public_encrypt($chunk, $encryptData, $pu_key,$this->padding);
            $crypto .= $encryptData;
        }
        return base64_encode($crypto);
    }

    // 解密
    public function decrypt($content)
    {
        if (!is_string($content)) return null;
                $decrypted = '';
        $chunks = str_split(base64_decode($content), 128);
        foreach ($chunks as $chunk) {
                    $partial = '';
            $decryptIsTrue = openssl_private_decrypt($chunk, $partial, $this->getPrivateKey());
            if ($decryptIsTrue === false) {
                            return null;
            }
            $decrypted .= $partial;
        }
        return $decrypted;
    }

    public function getPublicKey()
    {
        if ($this->key_format == self::PKCS1) {
            $search = [
                "-----BEGIN PUBLIC KEY-----",
                "-----END PUBLIC KEY-----",
                "\n",
                "\r",
                "\r\n"
            ];
            $public_key = str_replace($search, "", $this->rsa_public);
            $public_key = $search[0] . PHP_EOL . wordwrap($public_key, 64, "\n", true) . PHP_EOL . $search[1];
        } else {
            $public_key = $this->rsa_public;
        }
        $key = openssl_pkey_get_public($public_key);//这个函数可用来判断公钥是否是可用的
        if (!$key) {
            $this->throwError('公钥不可用');
        }
        return $key;
    }
    public function getPrivateKey()
    {
        if ($this->key_format == self::PKCS1) {
            $search = [
                "-----BEGIN PRIVATE KEY-----",
                "-----END PRIVATE KEY-----",
                "\n",
                "\r",
                "\r\n"
            ];
            $private_key = str_replace($search, "", $this->rsa_private);
            $private_key = $search[0] . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . $search[1];
        } else {
            $private_key = $this->rsa_private;
        }
        $pi_key = openssl_pkey_get_private($private_key);
        if (!$pi_key) {
            $this->throwError('私钥不可用');
        }
        return $pi_key;
    }
    public function throwError($msg)
    {
        throw new Exception($msg);
    }
}

二、调用方法

rsa加解密,普遍的是把自己的公钥给对方,使用彼此的公钥进行加密,然后使用

私钥进行解密的操作。这里只提供加解密以及签名案例

    //我自己的私钥
    private $private_key = '-----BEGIN RSA PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END RSA PRIVATE KEY-----';

    //对方的公钥
    private $public_key = '-----BEGIN PUBLIC KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END PUBLIC KEY-----';

  
    //定义需要加密的测试数据
   $bizContent=array(
        "supplierCode"=>"202372000142021000064",         
        "type"=>"1",                                                                                  
        "surrenderTime"=>"2021-09-10 15:30:00"                                       
   );
    //TODO 对数据进行签名以及加密
????$bizContent=json_encode($bizContent);
?   $utilRsa = new RSA($this->public_key , '');
    $bizContent_k = $utilRsa->encrypt($bizContent);

    //需要进行签名的数据串
    $sign='appKey=123123&bizContent='.$bizContent_k.'&charset=UTF-8&format=JSON&serviceName=serviceName&signType=RSA&timestamp=111111&version=1.0.0';

    //对sign进行私钥加密
    $sign_k= (new RSA('',$this->private_key))->sign($sign);
   
????//数据解密
    $res_bizContent = '需要解密的密文';
    $res = (new RSA('',$this->private_key))->decrypt($res_bizContent);
    $bizContent = json_decode($res,true);


三、注意细节

1、加密用的是对方的公钥,解密使用自己的私钥。

2、加解密的时候,会受到密文长度的限制报错,这时需要将密文分段加解密然后把结果在拼接起来

3、PHP的rsa加解密方法和Java还是有区别的,需要进行详细的沟通,了解具体的加密方法才可以匹配成功

4、第三方提供的java rsa秘钥(pkcs8格式),PHP不能直接使用;只能将rsa秘钥转成pkcs1格式,然后再按照PHP rsa秘钥格式处理。上面的加解密类有类似的方法


                
        
    
 

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 18:34:35  更:2021-09-11 18:35:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/19 7:32:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码