PHP 对接京东白条加解密+签名 AES/ECB/PKCS5Padding RSA/ECB/PKCS1Padding

对接最麻烦的是对方没有PHP的demo,只有java的代码,并且在相同的算法在PHP中和java是不同的写法。

签名验签

在java中签名使用的是SHA1withRSA算法,在PHP中对应的是openssl_sign默认算法,所以只需要按照以下代码编写即可:

    /**
     * 获取签名
     * @author shenzx
     * @date 2023-02-27 15:27
     */
    protected function setSign(){
        //获取私钥
        $privateKey = openssl_pkey_get_private(file_get_contents($this->privateKeyPath));
        //签名 如果失败openssl_sign会返回false
        openssl_sign($this->reqData, $sign, $privateKey);
        //释放私钥资源
        openssl_free_key($privateKey);
        //签名进行base64编码
        $sign = base64_encode($sign);
        //设置签名
        $this->sign = $sign;
    }
    /**
     * 验签
     * @author shenzx
     * @date 2023-02-28 11:27
     * @param $result 解密后的验签数据
     * @param $sign 京东返回的签名
     * @return bool|mixed
     * @throws \Exception
     */
    public function verifySign($result,$sign){
        //获取京东公钥
        $publicKey = openssl_pkey_get_public(file_get_contents($this->JdPublicKeyPath));
        //使用公钥进行签名验证
        $verify = (bool)openssl_verify($result, base64_decode($sign), $publicKey);
        //判断验签结果
        if($verify == false){
            throw new \Exception("验签失败");
        }
        //释放公钥
        openssl_free_key($publicKey);
        //验签成功 返回数据
        return $result;
    }

AES/ECB/PKCS5Padding算法

在京东的demo中它不止是单纯的AES/ECB/PKCS5Padding算法,还包含了SHA1PRNG,京东代码:

所以在PHP中我们应该这样写:

    //适用版本必须是PHP7+以上版本
    /**
     * 加密请求数据
     * @author shenzx
     * @date 2023-02-27 17:02
     * @return string
     */
    private function aesEncrypt($data,$password){
        $key = $this->_sha1prng($password);
        $iv = '';
        $data = openssl_encrypt($data, 'AES-128-ECB', $key, OPENSSL_RAW_DATA, $iv);
        $data = base64_encode($data);
        return $data;
    }

    /**
     * SHA1PRNG算法
     * @param  [type] $key [description]
     * @return [type]      [description]
     */
    private function _sha1prng($key)
    {
        return substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16);
    }

    /**
     * 解密返回数据
     * @author shenzx
     * @date 2023-02-28 11:19
     * @param $resData
     * @param $password
     * @return string
     */
    private function aesDecrypt($resData,$password){
        $password = $this->_sha1prng($password);
        $iv = '';
        $decrypted = openssl_decrypt(base64_decode($resData), 'AES-128-ECB', $password, OPENSSL_RAW_DATA, $iv);
        return $decrypted;
    }

 其中最容易忽略的就是SHA1PRNG算法,其他的我们按照AES-128-ECB算法加密即可。

RSA/ECB/PKCS1Padding算法

这个算法在PHP中只要按照正常的公私钥加解密写法编写即可,但是在第四个参数必须要加OPENSSL_PKCS1_PADDING设置填充模式

    /**
     * 京东公钥加密
     * @author shenzx
     * @date 2023-02-28 11:14
     * @return mixed
     */
    public function rsaPublicEncrypt($data,$JdPublicKeyPath)
    {
        //获取京东公钥
        $publicKey = openssl_pkey_get_public(file_get_contents($JdPublicKeyPath));
        //加密字符串
        $result  = openssl_public_encrypt($data, $encrypted, $publicKey,OPENSSL_PKCS1_PADDING);
        if (!$result)
        {
            throw new \Exception("秘钥加密失败");
        }
        $encrypted = base64_encode($encrypted);
        return $encrypted;
    }

    /**
     * 私钥解密返回数据 encryptKey
     * @author shenzx
     * @date 2023-02-27 17:02
     * @return string
     */
    private function rsaPrivateDecrypt($encryptKey,$privateKeyPath){
        $encryptKey = base64_decode($encryptKey);
        //获取私钥
        $privateKey = openssl_pkey_get_private(file_get_contents($privateKeyPath));
        //使用私钥进行解密
        $result = (bool)openssl_private_decrypt($encryptKey, $decrypted, $privateKey,OPENSSL_PKCS1_PADDING);
        //判断解密结果
        if($result == false){
            throw new \Exception("解密失败");
        }
        //释放私钥
        openssl_free_key($privateKey);
        return $decrypted;
    }

openssl_public_encrypt函数加密数据是有长度限制的,如果需要加密的数据太大,就需要分段加密

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值