通过 PHP 编码的字符串与使用 OpenSSL 的 SHELL 代码之间的区别

问题描述 投票:0回答:1

这两个代码是分开工作的,但即使它们依赖于同一个库,也不会给出相同的结果

他们俩:

  • 读取名为 plaintext.txt 的文件的内容
  • 根据提供的密钥创建 32 字节哈希值
  • 根据提供的初始化向量创建 16 字节哈希
  • 使用 AES-256-CBC 加密内容
  • 将base64编码的加密内容写入名为ciphertext.base64的文件中

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 个字符),这可能是警告“十六进制字符串太短,用零字节填充长度”的结果

php openssl cryptography
1个回答
0
投票

散列时,不会输出尾随换行符(使用 echo 的 -n 选项),并且必须考虑到在 OpenSSL 语句中选项 -K 和 -iv 需要十六进制编码的数据(因此必须另外添加 key 和 IV)是十六进制编码)。

可能的修复:

key='XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
secret_iv='YYYYYYYYY'

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

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

ct=$(echo -n 'The quick brown fox jumps over the lazy dog' | openssl enc -aes-256-cbc -e -K $keyhashhex -iv $ivhashhex -base64) 
echo $ct # rLEADKE4aSB9KVVUrxt5LxWKsTYe9pX0/ASuIRm2xpDm6dydMCD0adoF3yzeF/U4

通过此更改,两个代码的输出与相同的输入数据匹配,例如密文

rLEAD...eF/U4
为明文 敏捷的棕色狐狸跳过了懒狗

© www.soinside.com 2019 - 2024. All rights reserved.