php对接java接口(丁香医生)aes加解密-PKCS5Padding,rsa加解密

丁香医生

丁香要求的加密方式如下
在这里插入图片描述

<?php

namespace app\api\controller;
use app\common\controller\Api;
/**
 * 示例接口
 */
class Demo extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    /** @var string 版本 */
    protected $version = 'V1';

    /** @var string 客户编号 */
    protected $customId = '这里是客户编号,可以用测试的';

    /** @var string 请求的接口编号 请注意该值并不固定 每个接口不同 */
    protected $apiId = '接口是哪一一个';

    /** @var int 时间戳 */
    protected $timestamp;

    /** @var string 秘钥第二行的前48位 */
    protected $prefixPublicKey = '';

    /** @var string 加密算法 */
    protected $encryptType = 'AES-128-ECB';

    /** @var string 丁香公钥 */
    protected $publicKey = "";

    public function setTimestamp($timestamp): self
    {
        $this->timestamp = $timestamp;
        return $this;
    }

    /**
     * 拼接获取AES秘钥
     * @return string
     */
    protected function getAesKey(): string
    {
        return $this->version . $this->customId . $this->apiId . $this->timestamp . $this->prefixPublicKey;
    }
    /**
     * 数据data加密
     * @ApiMethod (POST)
     */
    public function test($timestamp, $data)
    {
        return $this->setTimestamp($timestamp)->encode($data);
    }
    protected function encode(array $data)
    {
        $data = openssl_encrypt(json_encode($data), $this->encryptType, $this->sha1prng($this->getAesKey()), OPENSSL_RAW_DATA);
        return base64_encode($data);
    }
    //SHA1PRNG算法
    protected function sha1prng(string $key)
    {
        return substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
    }

    /*
     * aes解密
     * */
    public function aesJi($sStr){
        $a = $sStr['timestamp'];
        $sStr = $sStr['data'];
        $sKey = $this->version . $this->customId . $this->apiId  ."$a". $this->prefixPublicKey;
        $sKeys = self::sha1prng($sKey);
        $decrypted = openssl_decrypt(base64_decode($sStr), 'AES-128-ECB', $sKeys, OPENSSL_RAW_DATA);
        return $decrypted;
    }

    //rsa加签 sha1WithRSA 签名
    public function genSign()
    {
        //公钥拼接
        $cert = "-----BEGIN PUBLIC KEY-----\n" . $this->publicKey . "\n-----END PUBLIC KEY-----";
        //解析公钥
        $res = openssl_pkey_get_public($cert);
        //返回包含密钥详情的数组
        $detail = openssl_pkey_get_details($res);
        //释放密钥资源
        openssl_free_key($res);
        $encrypt_data = '';
        //使用公钥加密数据
        openssl_public_encrypt($this->getAesKey(), $encrypt_data, $detail['key']);
        $encrypt_data = base64_encode($encrypt_data);
        return $encrypt_data;
    }
    //校验 sha1WithRSA 解签
    public function verifySign($data){
        $data1 = base64_decode($data['sign']);
//        halt($data);
        $cert = "-----BEGIN PUBLIC KEY-----\n" . $this->publicKey . "\n-----END PUBLIC KEY-----";
        $encrypt_data = '';
        $pubKey = openssl_public_decrypt($data1,$encrypt_data,$cert);
        if ($pubKey){
            return $this->aesJi($data);
        }
    }

    // post请求
    public function postSend($res)
    {
        header("Content-type: text/html; charset=utf-8");
        // 请求参数准备
        $url = "https://ygj.zydxcare.cn/manage/openapi/handle";
        $tojson = json_encode($res);
        $header[] = "Content-Type: application/json; charset=utf-8";
        $header[] = "Data-signature:C80310638874448266292D70EFA9340C";
        $header[] = "Time-stamp:1515577396000";
//        print_r($tojson);die();
        //初始化
        $ch = curl_init();
        // 设置请求地址
        curl_setopt($ch, CURLOPT_URL, $url);

        // 设置头文件
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        // 设置获取的信息以文件流的形式返回,而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置POST形式传参
        $a = curl_setopt($ch, CURLOPT_POST, 1);
        // 设置POST请求参数
        curl_setopt($ch, CURLOPT_POSTFIELDS, $tojson);
        // 设置ssl请求
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
//        var_dump(curl_error($ch));
        // 开始CURL请求
        $data = curl_exec($ch);
        // 关闭URL请求
        curl_close($ch);

//        print_r($data);die();
        //打印获得的数据
        $data = json_decode($data,true);
        if (empty($data['code'])){
            $this->error('错误');
        }

        return $data;
    }

    //拼接数据
    public function index()
    {
        $res = request()->post();
        $timestamp = $res['timestamp'];
        $da = $res['data'];
        $res['data'] = $this->test($timestamp, $da);
        $sign = $this->genSign();
        $data = [
            "apiId" => $res['apiId'],
            "customId" => $this->customId,
            "timestamp" => $res['timestamp'],
            "version" => $this->version,
            "data" => $res['data'],
            "sign" => $sign
        ];
        $information = $this->postSend($data);
        return $this->verifySign($information);
    }


}

请求如下
在这里插入图片描述

仿照实现接口加密方案

php代码

// 要加密的原始数据
$data = 'Hello, World!';

// 加密密钥
$key = 'YourEncryptionKey';

// 加密算法和加密模式
$algorithm = 'AES-256-CBC';
$ivLength = openssl_cipher_iv_length($algorithm);
$iv = openssl_random_pseudo_bytes($ivLength);

// 加密数据
$encryptedData = openssl_encrypt($data, $algorithm, $key, OPENSSL_RAW_DATA, $iv);

// Base64编码加密后的数据和初始化向量(IV)
$encryptedDataBase64 = base64_encode($encryptedData);
$ivBase64 = base64_encode($iv);

// 返回加密后的数据和IV给前端
return json(['encryptedData' => $encryptedDataBase64, 'iv' => $ivBase64]);

前端解密

// 接收前端传递的加密数据和IV
$encryptedDataBase64 = $_POST['encryptedData'];
$ivBase64 = $_POST['iv'];

// 解密密钥
$key = 'YourEncryptionKey';

// 解码加密数据和IV
$encryptedData = base64_decode($encryptedDataBase64);
$iv = base64_decode($ivBase64);

// 解密数据
$decryptedData = openssl_decrypt($encryptedData, $algorithm, $key, OPENSSL_RAW_DATA, $iv);

// 处理解密后的数据
echo $decryptedData;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值