建行生活H5对接求助

文档RSA demo![![![加解密实例]


调用demo

##用JAVA跑加解密一切正常
使用PHP openssl_pkey_get_private,openssl_private_decrypt系列函数解密都是空字符串,另外使用ChatGPT翻译JAVA代码成PHP也无法使用,有没有小伙伴对接过建行生活遇到这种情况

![这个是PHP测试代码]
![]

私钥里面的详参

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 27

方法什么的都没问题,分段解密不正确

3年前 评论
xiongy (楼主) 3年前

现成sdk都有,直接用Java

3年前 评论
xiongy (楼主) 3年前

有没有可能php的分块获取的大小有问题[doge]

3年前 评论
xiongy (楼主) 3年前
巅峰互联

www.cnblogs.com/xuan52rock/p/11023... 拿走 不谢。加密 算法 有不一致。

3年前 评论
xiongy (楼主) 3年前
巅峰互联

大致原因,PHP 加密 规则 java 加密规则不一致。你这边发生错误的原因,看看加密规则

3年前 评论
xiongy (楼主) 3年前
巅峰互联

想起来了, windows 下加密 使用功能的机制 和 linux 加密机制也不一致。 建议你在centos 环境下测试加密。自己分析过openssl 加密的源码,解释完毕。

3年前 评论
xiongy (楼主) 3年前
巅峰互联

这种情况。容易被。java同事误解 ,什么php 来个解密都 处理不了,认为PHP垃圾。 你就 接受他们的鄙视。

3年前 评论
xiongy (楼主) 3年前
巅峰互联

我当初是这么解决的。希望能帮助到你

3年前 评论
xiongy (楼主) 3年前
zhangatle

可以看一下官方文档描述这么写是否可行,加密用私钥,解密用公钥,解密用openssl_public_decrypt,文档链接

protected function decrypt_RSA($publicPEMKey, $data)
  {
    $decrypted = '';

    //decode must be done before spliting for getting the binary String
    $data = str_split(base64_decode($data), $this->DECRYPT_BLOCK_SIZE);

    foreach($data as $chunk)
    {
      $partial = '';

      //be sure to match padding
      $decryptionOK = openssl_public_decrypt($chunk, $partial, $publicPEMKey, OPENSSL_PKCS1_PADDING);

      if($decryptionOK === false){return false;}//here also processed errors in decryption. If too big this will be false
      $decrypted .= $partial;
    }
    return $decrypted;
  }
3年前 评论
xiongy (楼主) 3年前

之前遇到一次是openssl默认用128和Java加密对不上,改成sha-256规则加密一样了,只要有rsa这种openssl就和Java加密不一致

3年前 评论
xiongy (楼主) 3年前
laravel_peng
  • Java 使用的秘钥格式, PKCS8 的,比如上面截取你的代码:
    file

  • PHP 使用的是PKCS1 的,我之前对接过 Java 接口,使用 PKCS8 格式的秘钥是不行的。参考链接
    file

  • 但是 PKCS8 和 PKCS1 类型的秘钥是可以转换的(以下是支付宝助手工具提供的转换):
    file

  • 但也可以通过一些命令,参考链接
    file

3年前 评论
xiongy (楼主) 3年前

试下这个行吗,这个是浦发的;支付通道我大大小小对接了20多个,我的感受是没有php对接不了的支付通道;如果有,那一定是对接的姿势不正确

 public function decryptData($pfBodyData,$private_key)
    {

        $res = "-----BEGIN PRIVATE KEY-----\n" .
            wordwrap($private_key, 64, "\n", true) .
            "\n-----END PRIVATE KEY-----";
        $decodeStr    = base64_decode($pfBodyData);
        $privateKeyId = openssl_get_privatekey($res);
        $enArray = str_split($decodeStr, 1024 / 8);
        $decrypted = '';
        foreach ($enArray as $value) {
            openssl_private_decrypt($value,$decryptedTemp, $privateKeyId,OPENSSL_PKCS1_PADDING);
            $decrypted .= $decryptedTemp;
        }
        //$decrypted = '{"Channel":"1A31","TransAmt4":"000000000001","ChlTp":"1","MrchOrdrNo3":"211227143605083890995","Ccy4":"156","OrdrNo1":"1901122714360512614278380817","ThdPtySeq":"842021122722001431011442373204","OrdrSt":"00","TransDate":"20211227","PyBnkInfo":"610***@qq.com","TranTp1":"OD","MrchNo":"310130458130001","TerminalNo2":"90000002"}';
        Log::log('pf_pay_notify', '解密数据'.$decrypted);

        $decrypted = json_decode($decrypted,true);

        return $decrypted;
    }
3年前 评论
xiongy (楼主) 3年前

openssl版本问题 openssl v1.1以上版本是不支持128加密的

11个月前 评论
yangweijie

public static function encrypt(string $dataStr, string $publicKeyStr): string { echo "公钥分段加密开始\n";

    try {
        // 解码 Base64 公钥
        $publicKeyBytes = base64_decode($publicKeyStr);

        // 加载公钥
        $publicKey = PublicKeyLoader::load($publicKeyBytes)
            ->withPadding(RSA::ENCRYPTION_PKCS1);

        // 分段加密
        $data = $dataStr;
        $inputLen = strlen($data);
        $offset = 0;
        $encryptedBlocks = [];

        while ($inputLen - $offset > 0) {
            if ($inputLen - $offset > self::MAX_ENCRYPT_BLOCK) {
                $block = substr($data, $offset, self::MAX_ENCRYPT_BLOCK);
            } else {
                $block = substr($data, $offset);
            }
            $encryptedBlocks[] = $publicKey->encrypt($block);
            $offset += self::MAX_ENCRYPT_BLOCK;
        }

        $encryptedData = implode('', $encryptedBlocks);
        $encodedDataStr = base64_encode($encryptedData);

        echo "公钥分段加密完毕\n";

        return $encodedDataStr;
    } catch (Exception $e) {
        throw new Exception('RSA 加密失败: ' . $e->getMessage(), 0, $e);
    }
}

/**
 * 私钥分段解密。
 *
 * @param string $dataStr 解密内容,密文(Base64编码)。
 *                         支持单重或双重 Base64 编码的密文。
 * @param string $privateKeyStr 私钥(Base64编码)。
 * @return string 明文。
 * @throws Exception 当解密失败时。
 */
public static function decrypt(string $dataStr, string $privateKeyStr): string
{
    try {
        // 解码 Base64 私钥
        $privateKeyBytes = base64_decode($privateKeyStr);

        // 加载私钥
        $privateKey = PublicKeyLoader::load($privateKeyBytes)
            ->withPadding(RSA::ENCRYPTION_PKCS1);

        // 解码 Base64 密文
        $encryptedData = base64_decode($dataStr);

        // 尝试解密,支持单重和双重 Base64 编码
        $result = self::tryDecrypt($privateKey, $encryptedData);
        if ($result !== null) {
            return $result;
        }

        // 如果单重编码解密失败,尝试双重编码
        $doubleDecoded = base64_decode($encryptedData);
        if ($doubleDecoded !== false) {
            $result = self::tryDecrypt($privateKey, $doubleDecoded);
            if ($result !== null) {
                return $result;
            }
        }

        throw new Exception('Decryption error');
    } catch (Exception $e) {
        throw new Exception('RSA 解密失败: ' . $e->getMessage(), 0, $e);
    }
}
2天前 评论

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