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

如何将openssl加解密shell命令转换为PHP原生实现

解决方案:openssl enc加密命令转原生PHP实现

核心错误原因

  • openssl enc -k传入的是密码短语而非直接AES密钥,openssl默认通过EVP_BytesToKey算法结合随机盐、指定的MD5哈希派生实际使用的AES密钥和IV,不会直接用传入字符串作为密钥
  • 你之前的代码返回了md5($ciphertext_raw),返回值是密文的哈希结果而非密文本身,自然无法解密
  • openssl默认输出的加密结果固定以Salted__字符串为前缀,拼接8字节随机盐后再拼接密文,你之前的输出不符合该格式,所以解密时会报bad magic number错误
  • 直接传入十六进制格式的密钥时没有转成二进制,密钥长度不符合AES-256要求的32字节标准

完整可运行实现

function opensslEncryptAES256CBC(string $plaintext, string $passphrase): ?string
{
    // 完全对齐openssl默认的EVP_BytesToKey MD5派生逻辑
    function evpBytesToKey(string $salt, string $passphrase, int $keyLen = 32, int $ivLen = 16): string
    {
        $data = '';
        $result = '';
        while (strlen($result) < $keyLen + $ivLen) {
            $data = md5($data . $passphrase . $salt, true);
            $result .= $data;
        }
        return $result;
    }

    // openssl默认生成8字节随机盐
    $salt = openssl_random_pseudo_bytes(8);
    $keyIv = evpBytesToKey($salt, $passphrase);
    $key = substr($keyIv, 0, 32); // AES-256要求密钥长度为32字节
    $iv = substr($keyIv, 32, 16); // CBC模式要求IV长度为16字节

    // 加密得到二进制原始密文
    $ciphertextRaw = openssl_encrypt(
        $plaintext,
        'aes-256-cbc',
        $key,
        OPENSSL_RAW_DATA,
        $iv
    );

    if ($ciphertextRaw === false) {
        return null;
    }

    // 按openssl默认格式拼接后base64编码,和原shell命令输出完全兼容
    return base64_encode('Salted__' . $salt . $ciphertextRaw);
}

验证方法

// 测试示例
$passphrase = 'my_key';
$plaintext = 'email@gmail.com';
$encrypted = opensslEncryptAES256CBC($plaintext, $passphrase);
echo $encrypted . PHP_EOL;

// 命令行验证解密:echo 输出的加密字符串 | openssl enc -d -aes-256-cbc -a -k my_key -md md5

兼容说明

如果需要使用固定盐/IV测试,把openssl_random_pseudo_bytes(8)替换为对应盐的二进制值即可;如果是直接使用预生成的十六进制密钥,调用前用hex2bin()将十六进制密钥转成32字节二进制值再传入加密函数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:48:02