Java的Rsa公钥解密转php,求解

1. 运行环境

1). 当前使用的 Laravel 版本?

Laravel 9

2). 当前使用的 php/php-fpm 版本?

PHP 版本:8,0

3). 业务环境

开发环境

2. 问题描述?

有一段java的demo,用rsa公钥解密的。该如何用php实现

package com.test;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;

import java.nio.charset.Charset;

/**
 * 3.0api 加解密 加签验签
 *
 * @author Admin
 */
public class VerifyRsaTest {


    /**
     * 加解密 加签验签
     */
    public static void main(String[] args) throws Exception {


        String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB";
        String aa="C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==";

        String str =  URLUtil.decode(aa, Charset.defaultCharset(),false);

        String decrypt = decryptRsaPublicKey(str, publicKey);
        System.out.println("对接方解密,decrypt = " + decrypt);

    }

    // RSA公钥解密
    public static String decryptRsaPublicKey(String targetData, String publicKeyBase64) {
        // RSA公钥解密
        RSA rsa = SecureUtil.rsa(null, publicKeyBase64);
        byte[] decrypt = rsa.decrypt(Base64.decode(targetData), KeyType.PublicKey);
        return new String(decrypt, CharsetUtil.CHARSET_UTF_8);
    }
}

我尝试用下面的php代码,无法解密。解密出来是null。请问该如何才能用php实现

        $publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB";
        $txt="C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==";
        //        $txt = urldecode($txt);
        $publicKey = "-----BEGIN PUBLIC KEY-----\n"
        . wordwrap($publicKey, 64, "\n", true)
        . "\n-----END PUBLIC KEY-----";
        $publicKeyResource = openssl_pkey_get_public($publicKey);
        openssl_public_decrypt(base64_decode($txt), $decryptedData, $publicKeyResource);
        dd($decryptedData);

3. 您期望得到的结果?

{“amt”:1000.0000,”createTime”:1694663267000,”errorCode”:”36020”,”errorMsg”:”账户可用余额不足”,”idCard”:”500231198602096055”,”merchantBatchId”:”20230914114746614223”,”merchantId”:1701443988206407682,”merchantOrderId”:”202309141147466142231”,”mobile”:”13983211095”,”orderBatchNo”:”202309141147478V2Y1X”,”orderNo”:”202309141147478V2Y1X00001”,”payeeAcc”:”oDely66AF4G-lD17AZTSx6D_rTLk”,”payeeName”:”杨小军”,”platFee”:0.0000,”splitFlag”:”0”,”status”:”60”,”tradeEndTime”:1694663267000}

4. 您实际得到的结果?

null

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
最佳答案

RSA 对原文长度(根据密钥)是有要求的,hutool 里面会自动切片处理,php 不会的,要手动处理,按照 128 切片就好了。


function decryptRsaPublicKey($targetData, $publicKeyBase64)
{
    // 构建公钥
    $publicKey = "-----BEGIN PUBLIC KEY-----\n" .
        chunk_split($publicKeyBase64, 64, "\n") .
        '-----END PUBLIC KEY-----';

    // 将目标数据进行 Base64 解码
    $decodedData = base64_decode($targetData);

    // 加载公钥
    $keyResource = openssl_pkey_get_public($publicKey);
    if (!$keyResource) {
        throw new Exception('Invalid public key');
    }

    $decrypted = '';
    $maxLength = 128; // 1024位密钥的块大小为128字节
    $offset = 0;

    // 分片解密
    while ($offset < strlen($decodedData)) {
        $chunk = substr($decodedData, $offset, $maxLength);
        $offset += $maxLength;
        $decryptedChunk = '';

        // 公钥解密
        if (!openssl_public_decrypt($chunk, $decryptedChunk, $keyResource)) {
            throw new Exception('Failed to decrypt data');
        }
        $decrypted .= $decryptedChunk;
    }

    // 释放密钥资源
    openssl_free_key($keyResource);

    return $decrypted;
}

// 测试数据
$publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB';
$txt = 'C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==';


$d = decryptRsaPublicKey($txt, $publicKey);


var_dump($d);
// string(489) "{"amt":1000.0000,"createTime":1694663267000,"errorCode":"36020","errorMsg":"账户可用余额不足","idCard":"500231198602096055","merchantBatchId":"20230914114746614223","merchantId":1701443988206407682,"merchantOrderId":"202309141147466142231","mobile":"13983211095","orderBatchNo":"202309141147478V2Y1X","orderNo":"202309141147478V2Y1X00001","payeeAcc":"oDely66AF4G-lD17AZTSx6D_rTLk","payeeName":"杨小军","platFee":0.0000,"splitFlag":"0","status":"60","tradeEndTime":1694663267000}"
3周前 评论
神的孩子丶都在跳舞 (楼主) 3周前
讨论数量: 6

RSA 对原文长度(根据密钥)是有要求的,hutool 里面会自动切片处理,php 不会的,要手动处理,按照 128 切片就好了。


function decryptRsaPublicKey($targetData, $publicKeyBase64)
{
    // 构建公钥
    $publicKey = "-----BEGIN PUBLIC KEY-----\n" .
        chunk_split($publicKeyBase64, 64, "\n") .
        '-----END PUBLIC KEY-----';

    // 将目标数据进行 Base64 解码
    $decodedData = base64_decode($targetData);

    // 加载公钥
    $keyResource = openssl_pkey_get_public($publicKey);
    if (!$keyResource) {
        throw new Exception('Invalid public key');
    }

    $decrypted = '';
    $maxLength = 128; // 1024位密钥的块大小为128字节
    $offset = 0;

    // 分片解密
    while ($offset < strlen($decodedData)) {
        $chunk = substr($decodedData, $offset, $maxLength);
        $offset += $maxLength;
        $decryptedChunk = '';

        // 公钥解密
        if (!openssl_public_decrypt($chunk, $decryptedChunk, $keyResource)) {
            throw new Exception('Failed to decrypt data');
        }
        $decrypted .= $decryptedChunk;
    }

    // 释放密钥资源
    openssl_free_key($keyResource);

    return $decrypted;
}

// 测试数据
$publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB';
$txt = 'C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==';


$d = decryptRsaPublicKey($txt, $publicKey);


var_dump($d);
// string(489) "{"amt":1000.0000,"createTime":1694663267000,"errorCode":"36020","errorMsg":"账户可用余额不足","idCard":"500231198602096055","merchantBatchId":"20230914114746614223","merchantId":1701443988206407682,"merchantOrderId":"202309141147466142231","mobile":"13983211095","orderBatchNo":"202309141147478V2Y1X","orderNo":"202309141147478V2Y1X00001","payeeAcc":"oDely66AF4G-lD17AZTSx6D_rTLk","payeeName":"杨小军","platFee":0.0000,"splitFlag":"0","status":"60","tradeEndTime":1694663267000}"
3周前 评论
神的孩子丶都在跳舞 (楼主) 3周前

RSA 对原文长度(根据密钥)是有要求的,hutool 里面会自动切片处理,php 不会的,要手动处理,按照 128 切片就好了。


function decryptRsaPublicKey($targetData, $publicKeyBase64)
{
    // 构建公钥
    $publicKey = "-----BEGIN PUBLIC KEY-----\n" .
        chunk_split($publicKeyBase64, 64, "\n") .
        '-----END PUBLIC KEY-----';

    // 将目标数据进行 Base64 解码
    $decodedData = base64_decode($targetData);

    // 加载公钥
    $keyResource = openssl_pkey_get_public($publicKey);
    if (!$keyResource) {
        throw new Exception('Invalid public key');
    }

    $decrypted = '';
    $maxLength = 128; // 1024位密钥的块大小为128字节
    $offset = 0;

    // 分片解密
    while ($offset < strlen($decodedData)) {
        $chunk = substr($decodedData, $offset, $maxLength);
        $offset += $maxLength;
        $decryptedChunk = '';

        // 公钥解密
        if (!openssl_public_decrypt($chunk, $decryptedChunk, $keyResource)) {
            throw new Exception('Failed to decrypt data');
        }
        $decrypted .= $decryptedChunk;
    }

    // 释放密钥资源
    openssl_free_key($keyResource);

    return $decrypted;
}

// 测试数据
$publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyxVgchYx/xx3jWyKPxb4s7boVOSDLxu7MP2U0NNAqtWSNMRRF+5sAjMd3RyeftsRT/QWAf2Rs9P/oZikGP0yqpsrWYHgbLcYLqIsgNPr6yOk855gvHB5szRsQggK0d4hl562Lx5T9DvHuM5u2jChsqZ7PvRXmNa+SDBtEB/3fnwIDAQAB';
$txt = 'C5rKZS/HWcEcaSFVyjmmOThYeEaEUwzK7kJf9NK5MkzkWxFH7VoQJS77c19jm9mt1YlhL5RGIficRi2W2+O8yMsT1Jps/7zvtzgV3lMp4ZBWciRg7/UU5CJq/CrVtfxHYrNQKn5eFTpaDX/cENb8u47vxtjZpwPhbNIc7HSCCLVZ0qSUgKCFHS/JNMGnin8rpCOL0ON5nEzmJnyDhlQikTVDTgDYdDyGokOkGnIUrD9JcMQ0sSLQXRk3qT3zfCAamgRWhDUDgUG+7HHoya5nFwjJ+UHq7pfxcu+gFDDWvHqAN1q+ayl1kb7hf0NSYjG0/d/MB2LT5XLxhDgVIQSwGiHRB/1nHIiNJGQnEirtsNcGSl9hXZ7PPaAm5Oo2gadIFh8ro0BKwnlmha6WmRS47sf7De3zlRVeSLWYXJYyniFj9+LumdUOgwWaZHrJXSpQSTj2GQtwLy0yjirkWKJXt2YfpeEXsUpaZib0Rbo8yuruvZqM1aAKtMwGRdBwTvKXECA6uCqizBPBtyNRRAUL7AvwZCKHJQdAY1u4yhKngDYEwO651PPVO/IkKw9CbC4mRpfhD5sIFoqIcFyl0f4ns/USip5gKUofKGv0hStQD8Hq9JIQEvR9M5lkx2KZarudIttZiZKycqMUA4xCHsJetbohBDQwMHY3I0tsKjy3WuiWbzJsuJrQD4qfbp72UOKjD+zdeyTzykdKOPEYvmsEucSlubFrd8jmQlyWjR/3roQCqlhGlZmH7CGf+epSewULOjQP6geUh1Zl2p0CJNBNd8olCqIHFt4AQqb1GhdVLcDpOg63HBGj8O+WiLbM9sE7umDYizmC7ImNIQ0mPRPuBw==';


$d = decryptRsaPublicKey($txt, $publicKey);


var_dump($d);
// string(489) "{"amt":1000.0000,"createTime":1694663267000,"errorCode":"36020","errorMsg":"账户可用余额不足","idCard":"500231198602096055","merchantBatchId":"20230914114746614223","merchantId":1701443988206407682,"merchantOrderId":"202309141147466142231","mobile":"13983211095","orderBatchNo":"202309141147478V2Y1X","orderNo":"202309141147478V2Y1X00001","payeeAcc":"oDely66AF4G-lD17AZTSx6D_rTLk","payeeName":"杨小军","platFee":0.0000,"splitFlag":"0","status":"60","tradeEndTime":1694663267000}"
3周前 评论
神的孩子丶都在跳舞 (楼主) 3周前

博客:关于php rsa加密处理 我之前还踩过坑

3周前 评论
神的孩子丶都在跳舞 (楼主) 3周前
kolin (作者) 3周前

之前需要对接一个 Java 的项目,给同事写了个 DEMO,Laravel Command 可直接运行

<?php

declare(strict_types=1);

namespace App\Console\Commands;

use Illuminate\Console\Command;

class Sign extends Command
{
    protected const PRIVATE_KEY = '私钥';

    protected const PUBLIC_KEY = '公钥';

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:sign';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $data      = '香香最牛逼';
        $encrypted = ($this->encrypt($data));
        $encrypted = 'VF905Vfio976MOMFh2379dVCwr2ALL7Eb8ul4UbvxJyjj4PNlJ40MIZ2bbUl9Uf5QjlP/06ucJQYln9S5G+LD7w+YviP5g1QkO+TFK5tY6oEjnrMW4/2ANXPqE2Srf9fDNIicIk/Fo3KxgAtXBNI4IsnD5EMan34Xy7mH4yLNhuBVTkZ5bEat33yx8QfN+83mMn+NjCkqVDVX0wDooT263r7jusPYxxmsmE3fw1XJBBVs9je0ms2+O3zU2h1i8tMART28ZeLhIPShJiGSFZd2M5NrirefVRRkg/kyyLDzIwUJqx3z2b0aTmu9mNU7HnrMGDFGQySVMBm67aoYjb7Pg==';
        $encrypt   = ($this->decrypt($encrypted, self::getPrivateKey()));
        $sign      = $this->sign($data);
        dd($this->verifySign($sign, $data));
    }

    public function encrypt(string $data)
    {
        $public_key    = ($this->formatPublicKey(self::PUBLIC_KEY));
        $publicKey     = openssl_pkey_get_public($public_key);
        $blockSize     = 117; // 使用 117 字节的块大小
        $dataBytes     = $data;
        $inputLen      = strlen($dataBytes);
        $offset        = 0;
        $encryptedData = '';

        while ($inputLen - $offset > 0) {
            if ($inputLen - $offset > $blockSize) {
                $chunk = substr($dataBytes, $offset, $blockSize);
                openssl_public_encrypt($chunk, $encryptedChunk, $publicKey, OPENSSL_PKCS1_PADDING);
            } else {
                $chunk = substr($dataBytes, $offset, $inputLen - $offset);
                openssl_public_encrypt($chunk, $encryptedChunk, $publicKey, OPENSSL_PKCS1_PADDING);
            }
            $encryptedData .= $encryptedChunk;
            $offset += $blockSize;
        }

        // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
        // 加密后的字符串
        return base64_encode($encryptedData);
    }

    protected static function getPublicKey(): string
    {
        return self::PUBLIC_KEY;
    }

    protected static function getPrivateKey(): string
    {
        return self::PRIVATE_KEY;
    }

    protected function verifySign(string $sign, $data)
    {
        $pk        = $this->formatPublicKey(self::getPublicKey());
        $publicKey = openssl_pkey_get_public($pk);
        $result    = openssl_verify($data, base64_decode($sign), $publicKey, OPENSSL_ALGO_SHA256);

        return $result === 1;
    }

    protected function sign(string $data)
    {
        $private_key = self::formatPrivateKey(self::getPrivateKey());
        $priv_key    = openssl_pkey_get_private($private_key);
        $sign        = '';
        if (openssl_sign($data, $sign, $private_key, OPENSSL_ALGO_SHA256)) {
            return base64_encode($sign);
        }
        throw new Exception('Failed to sign data');
    }

    protected function decrypt($data, $privateKeyStr)
    {
        $priKeyFormatted = $this->formatPrivateKey($privateKeyStr);
        $privateKey      = openssl_pkey_get_private($priKeyFormatted);
        if (! $privateKey) {
            throw new Exception('Private key is not valid');
        }

        $data          = base64_decode($data);
        $decryptedData = '';
        $offset        = 0;
        $dataLength    = mb_strlen($data, '8bit');
        while ($dataLength > $offset) {
            $chunk = mb_substr($data, $offset, 256, '8bit');
            if (! openssl_private_decrypt($chunk, $decryptedChunk, $privateKey, OPENSSL_PKCS1_PADDING)) {
                throw new Exception('Failed to decrypt data');
            }

            $decryptedData .= $decryptedChunk;
            $offset += 256;
        }

        return $decryptedData;
    }
    protected function formattedPublicKey(): string
    {
        return "-----BEGIN PUBLIC KEY-----\n" . chunk_split(self::getPublicKey(), 64, "\n") . '-----END PUBLIC KEY-----';
    }

    private function formatPrivateKey($privateKeyStr)
    {
        return "-----BEGIN PRIVATE KEY-----\n" . chunk_split($privateKeyStr, 64, "\n") . '-----END PRIVATE KEY-----';
    }

    private function formatPublicKey($publicKeyStr)
    {
        return "-----BEGIN PUBLIC KEY-----\n" . chunk_split($publicKeyStr, 64, "\n") . '-----END PUBLIC KEY-----';
    }
}

3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!