You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP openssl_encrypt加密内容无法用Python pyca/cryptography解密求助

问题分析与解决

核心问题出在PHP的密钥处理环节:你在PHP中使用hash_pbkdf2时将最后一个参数raw_output设为FALSE,这会返回十六进制编码的字符串,但openssl_encrypt需要的是原始二进制格式的密钥。此时PHP实际使用的是十六进制字符串的ASCII字节作为密钥,而非PBKDF2推导的原始二进制密钥,导致和Python端的密钥逻辑不匹配,最终解密失败。

修正后的PHP脚本

将hash_pbkdf2的raw_output参数改为TRUE,直接获取原始二进制密钥:

<?php

    $pass = "password";
    $salt = "salt";
    $data = "here is a test message";
    $cipher = "aes-256-cbc";
    $options = OPENSSL_RAW_DATA;
    $rnds = 1024;
    $klen = 32; // AES-256固定需要32字节密钥,无需设为64

    // 改为raw_output=TRUE,获取原始二进制密钥
    $key = hash_pbkdf2("sha256", $pass, $salt, $rnds, $klen, TRUE);
    echo("Key hex = '" . bin2hex($key) . "'<br>");

    $iv = openssl_random_pseudo_bytes(16);
    $enc = openssl_encrypt($data, $cipher, $key, $options, $iv);

    echo("IV = '" . base64_encode($iv) . "'<br>");
    echo("Encrypted = '" . base64_encode($enc) . "'<br>");

?>

补充说明

  • AES-256固定需要32字节密钥,因此$klen直接设为32即可,避免生成不必要的字节。
  • 用bin2hex($key)输出密钥的十六进制形式,方便和Python端的key.hex()结果对比验证。

验证Python脚本

使用修正后的PHP输出的IV和密文,Python脚本无需修改即可正常解密:

import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

kdf = PBKDF2HMAC(
    algorithm=hashes.SHA256(),
    length=32,
    salt=b'salt',
    iterations=1024
)
key = kdf.derive(b'password')
print(key.hex())

iv = base64.b64decode('修正后的IV')
enc = base64.b64decode('修正后的密文')

cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
plain = decryptor.update(enc) + decryptor.finalize()

print(plain.decode('utf-8'))  # 输出: here is a test message

内容的提问来源于stack exchange,提问作者barneyAgumble

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:23:26