【问题标题】:AES encrypt in Terminal and decrypt in PHPAES 在终端中加密并在 PHP 中解密
【发布时间】:2017-12-09 12:46:23
【问题描述】:

我遇到过其他有类似问题的主题,但由于 PHP 的最新变化(即 mcrypt 删除),我正在寻求一些关于我最好如何处理的建议这在 2017/18 年使用 OpenSSL。

在 Mac 终端中使用echo 'this string will be encrypted' | openssl enc -aes-256-cbc -a -pass pass:123,我能够对字符串进行密码加密,现在想将其(作为参数)传递给服务器端 PHP 函数进行解密。

研究了this 问题,我可以看到这是可能的,但它使用了现在删除的 mcrypt 函数。进一步阅读PHP manual,我还没有弄清楚如何将此加密命令反转为其 PHP 解密等效项。

This recent answer 是我迄今为止实现的,但它不能与终端生成的加密一起使用,只有在 PHP 中创建的加密(此处未显示)。

<?php
  $encrypted_string = $_GET['data'];
  $password = '123';
  $decrypted_data = openssl_decrypt($encrypted_string, "AES-256-CBC", $password);
  print "Decrypted Data: <$decrypted_data>\n";
?>

OpenSSL PHP 手册指出纯文本或 base64 编码字符串都可以传入和解密。由于我在加密过程中使用了-a 标志,因此我希望传入base64,从而消除源作为未返回解密数据的潜在原因。

我已经处理了 URL 编码,以便将加密算法产生的任何 + 符号替换为它们的 - %2B - URL-Safe 等效项,否则它们会变成空格字符,从而破坏了参数字符串。这进一步确保了已编码的输入字符串被解密算法正确寻址。

问题: 为什么我的 PHP 函数不能解密终端命令生成的字符串,尽管它们使用相同的方法和密码?我的 PHP 代码中缺少什么可以使它正常工作?

大家干杯。

更新

我现在正在使用终端命令:
echo 'blah' | openssl enc -aes-256-cbc -a -K B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF -iv 64299685b2cc8da5 加密为:Y4xelTtEJPUHytB5ARwUHQ==

我使用 www.example.com/?data=Y4xelTtEJPUHytB5ARwUHQ== 将它传递给 PHP

PHP 应该获取数据参数并解密。目前,该函数如下所示:

<?php
$encrypted_string = base64_decode($_GET['data']);
$key = 'B374A26A71490437AA024E4FADD5B497FDFF1A8EA6FF12F6FB65AF2720B59CCF';
$iv = '64299685b2cc8da5';

$output = openssl_decrypt($encrypted_string, 'AES-256-CBC', hex2bin($key), OPENSSL_RAW_DATA, hex2bin($iv));
print "Decrypted Data: <$output>\n";
?>

【问题讨论】:

  • 回想一下,AES 只对特定的密钥大小进行操作。您使用 AES-256 加密并且只传递 24 位密钥(“123”)。这是可能的,因为 OpenSSL 使用 KDF 从该密码中派生出可接受长度的密钥。 openssl_decrypt 函数不会 这样做,因此通过传递 123 作为键,您已经在调用未定义的行为。您应该确定 OpenSSL 使用的 KDF 是什么,并将其复制到您的 PHP 代码中。
  • @LukePark 我整个周末都尝试了各种长度的值和函数。包括更改键中的字符数。然而,我不明白为什么终端中的 OpenSSL 与 PHP 中的 OpenSSL 解密命令不兼容。有人能给出一个与我的问题上下文相关的代码示例吗?我可以分别在终端和 PHP 中加密/解密,但不能以某种语言加密并用另一种语言解密。非常感谢任何帮助。
  • 你看了我的回复还是...?你做了我说你需要做的事吗? KDF 是最重要的。

标签: php security encryption terminal cryptography


【解决方案1】:

OpenSSL 使用专有的 KDF,您可能不希望在 PHP 代码中重现它。但是,您可以使用 -K 标志将密钥作为纯十六进制传递,避免使用 KDF:

echo 'blah' | openssl enc -aes-256-cbc -K 0000000000000000000000000000000000000000000000000000000000000000

这里,大的十六进制字符串是您的 256 位密钥,十六进制编码。此加密操作将与您的 PHP 兼容。

【讨论】:

  • 感谢您的澄清。为了获得对 URL 友好的字符串,我在方法后面添加了 -a 标志,就像在我的原始帖子中一样。从终端运行上面的代码返回iv undefined,所以我在末尾添加了-iv,以及另一个值,但是PHP 说:Warning: openssl_decrypt: IV passed is 32 bytes long which is longer than the 16 expected by selected cipher... 用简单的英语来说是有意义的,所以我取消了 1/2 并再次开始加密(这次只使用了-iv 参数中一半的字符)。在另一边解密它没有运气。
  • @ProGrammer 你在 PHP 代码中也使用了 IV 吗?
  • @ProGrammer IV 应该是 16 个字节而不是 8 个。您也不是 base64 来决定 PHP 中的密文..
  • @ProGrammer 它是十六进制编码的......每个字节两个字符,所以IV只有8个字节。长度加倍...
  • 我设法通过在$output 行中包含hex2bin() 函数来使解密部分正常工作。谢谢你。我现在想改变方向:stackoverflow.com/questions/47768006/… 也许这是您可能有兴趣帮助我的事情。再次感谢。
猜你喜欢
  • 2020-12-23
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 2012-04-18
相关资源
最近更新 更多