这两个代码单独工作,但即使它们依赖于相同的库,也不会产生相同的结果

他们俩:

  • 读取名为Plavext.txt的文件的内容
  • 从提供的键创建一个32字节的哈希
  • 从提供的初始化向量创建16字节哈希
  • 使用AES-256-CBC对内容进行加密
  • 将以Base64编码的加密内容写入名为cipherext.base 64的文件中

PHP

<?php

$encrypt_method = "AES-256-CBC";
$secret_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$secret_iv = 'YYYYYYYYY';

// hashes
$key = substr(hash('sha256', $secret_key), 0, 32);
$iv = substr(hash('sha256', $secret_iv), 0, 16);

$string = file_get_contents('plaintext.txt');

$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
//By default the output is already in base64
file_put_contents('ciphertext.base64', $output);
?>

巴什

key='XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
secret_iv='YYYYYYYYY'

keyhash=$(echo -n $key | sha256sum | cut -c 1-32)
ivhash=$(echo -n $secret_iv | sha256sum | cut -c 1-16)

openssl enc -aes-256-cbc -e -K "$keyhash" -iv "$ivhash" -in plaintext.txt -out ciphertext.base64 -base64

我真的不明白为什么结果会不一样.此外,在php中,IV的长度必须为16,而shell 程序报告的长度应该是32

有什么建议吗?

在bash中,我注意到32个0被添加到key(64个字符),16个0被添加到IV(32个字符),这可能是警告"十六进制字符串太短,用零字节填充长度"的结果.

推荐答案

While the key and IV in PHP/OpenSSL must be passed as raw values (i.e. binary strings) to openssl_encrypt(), they must be specified hex encoded in the OpenSSL statement (s. openssl-enc, -K. -iv options).
Both are not done correctly in the code (possibly because, as already suspected in the comment, binary and hex encoded data are confused):

  • 在PHP代码中,对于键和IV,使用的不是原始散列值,而是十六进制编码的散列值.direct使用十六进制编码的哈希值是一个漏洞,因 for each 字节的取值范围从256个字节减少到16个字节.因此,这个问题应该得到解决.为此,必须将hash()函数的第三个参数设置为true:

    $key = hash('sha256', $secret_key, true);
    $iv = substr(hash('sha256', $secret_iv, true), 0, 16); 
    
  • 在bash脚本中,十六进制编码的散列值被截断.要解决此问题,请使用正确的长度(64个十六进制数字或32个字节用于密钥,32个十六进制数字或16个字节用于IV):

    keyhash=$(echo -n $key | sha256sum)                      
    ivhash=$(echo -n $secret_iv | sha256sum | cut -c 1-32)   
    

如果PHP代码不能/不应该改变,尽管有上述缺点,十六进制编码的值将直接用作键和IV,则需要在批处理脚本中添加额外的十六进制编码:

keyhashstr=$(echo -n $key | sha256sum | cut -c 1-32)               
keyhash=$(printf '%s' $keyhashstr | hexdump -ve '/1 "%02X"')
ivhashstr=$(echo -n $secret_iv | sha256sum | cut -c 1-16)               
ivhash=$(printf '%s' $ivhashstr | hexdump -ve '/1 "%02X"')

(或者使用xxd而不是hexdump).


Security: Regarding the term secret_iv: The IV is not a secret and therefore does not need to be kept secret. However, it is a vulnerability if a static IV is used, as this results in a reuse of key/IV pairs if the same key is used. To prevent this, a common approach is to generate a random IV for each encryption. The IV is passed together with the ciphertext to the decrypting side, usually concatenated.
When using a passphrase, another vulnerability is to use a fast digest for key derivation. More secure is a key derivation function such as PBKDF2 in conjunction with a random (also not secret) salt.

Php相关问答推荐

根据类别在WooCommerce中添加库存数量后缀

为什么注册SIGHUP的处理程序函数会阻止在PHP CLI中等待输入时点击X关闭Xterm窗口?""

我需要多个SELECT语句的结果(使用由php ECHO创建的表中显示的Limit(X)

WooCommerce数量减号和加号图标未显示

免费送货柜台,考虑到折扣码

PHP -将字符串拆分为两个相等的部分,但第二个字符串中的单词更多

用GUZLE模拟Read_Timeout

Laravel 10中的Validator类

将数据推入所有子数组条目

强制客户在注册时 Select WooCommerce角色

invalid_grant 和无效的 JWT 签名

WooCommerce 中一件免费产品的数量折扣

批量更新 WooCommerce 中所有产品的特定自定义字段

在 vue 自定义渲染器中访问变量

在PHP WordPress插件中使用变量连接路径时的问题解决方法

Woocommerce API 的 PHP Curl 附加参数

yii2 sql迁移覆盖新更改的记录

在 laravel 中更新表单时如何在 Select 选项中保留旧值?

php-http/discovery 插件 1.15.1 是否仍在使用自己的模块 destruct Contao 4.13 中的composer 安装?

如何在不复制的情况下在php中重新索引数组