【问题标题】:Encrypt / Decrypt openSSL between Windows PC and PHP running on Linux Web Server在 Windows PC 和 Linux Web 服务器上运行的 PHP 之间加密/解密 openSSL
【发布时间】:2017-07-05 16:05:53
【问题描述】:

我正在尝试学习如何在 Windows 64 机器(我的 PC)和使用 openSSL 在 Linux Web 服务器上运行的 PHP 之间执行简单的加密/解密。

在我的 Windows 机器上,我已经为 Win64 安装了 OpenSSL v1.0.2k,我正在使用以下命令使用简单密码和位于 secretkey 中的简单密钥创建加密字符串。文本文件。

enc -aes-256-cbc -A -base64 -nopad -nosalt -pass pass:hello -in secretkey.txt

当我运行上面的命令时,我得到以下字符串:

3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=

使用上面的字符串,我希望我的 Linux Web 服务器上的 PHP 能够像这样解密它:

 $encrypted = '3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=';
 $enc = 'aes-256-cbc';
 $password = 'hello';
 $key = openssl_decrypt($encrypted, $enc, $password, OPENSSL_ZERO_PADDING);
 echo $key .' should equal this-1234-is-4567-my-8910-secret';

但是,我得到了这个:

9(j����T]��$�W�Ma��S�è��zz�>.( 应该等于 this-1234-is-4567-my-8910-secret

我查看了以下网站并尝试了多个版本,但无法正确解密:

Open SSL Enc
Open SSL Command Line
PHP Decrypt

【问题讨论】:

  • 不是重复的。问题是关于尝试从命令行(windows)加密并使用php解密。推荐的解决方案是全部在 PHP 中进行加密和解密。
  • 您是否对 PHP 代码中的 openssl 输出进行 base64 解码?
  • 零填充是一个糟糕的主意,通常使用 PKCS#7(née PKCS#5)填充。零填充将不允许加密恰好以零 (0x00) 字节结尾的二进制数据。

标签: php encryption openssl php-openssl


【解决方案1】:

AES 需要 key 才能工作。这是一个精确长度的字节序列(在 AES-256 的情况下为 32)。您不能直接使用密码(除非构成密码的字节恰好是正确的长度)。

此外,CBC mode 需要一个 16 字节的初始化向量 (IV)。

OpenSSL enc 命令从使用内部函数 EVP_BytesToKey 提供的密码中派生要使用的密钥和 IV。为了解密已使用enc 加密的文件,您需要重现此功能。该算法的详细信息在文档中。在 PHP 中,它可能看起来像这样:

$password = 'hello';

$bytes = "";
$last = "";

// 32 bytes key + 16 bytes IV = 48 bytes.
while(strlen($bytes) < 48) {
    $last = md5($last . $password, true);
    $bytes.= $last;
}

// First 32 bytes are the key, next 16 are the IV.
$key = substr($bytes, 0, 32);
$iv = substr($bytes, 32, 16);

然后您可以在openssl_decrypt 命令中使用这些值:

$enc = 'aes-256-cbc';
$result = openssl_decrypt($encrypted, $enc, $key, OPENSSL_ZERO_PADDING, $iv);

【讨论】:

    猜你喜欢
    • 2011-06-12
    • 2018-12-04
    • 2011-10-24
    • 2014-07-12
    • 2011-09-30
    • 1970-01-01
    • 2020-05-18
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多