我一直在尝试在 PHP 中实现与 C 中完全相同的函数。但是,我还没有看到完全相同的结果。我认为问题在于“计数”或迭代,我仍然不完全理解。
函数定义:
int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
const unsigned char *salt, const unsigned char *data, int datal,
int count, unsigned char *key, unsigned char *iv)
以下是 C 函数实现的链接:evp_key.c
.
这是我在 Stack Overflow 上找到的内容,很接近,但没有作者简要提到的“计数”:Encrypting data in Cocoa, decoding in PHP 。用户myztikjenz提供的关键行在这里:
$cipher = MCRYPT_TRIPLEDES;
$cipherMode = MCRYPT_MODE_CBC;
$keySize = mcrypt_get_key_size( $cipher, $cipherMode );
$ivSize = mcrypt_get_iv_size( $cipher, $cipherMode );
$rawKey = "ThisIsMyKey";
$genKeyData = '';
do
{
$genKeyData = $genKeyData.md5( $genKeyData.$rawKey, true );
} while( strlen( $genKeyData ) < ($keySize + $ivSize) );
$generatedKey = substr( $genKeyData, 0, $keySize );
$generatedIV = substr( $genKeyData, $keySize, $ivSize );
$output = mcrypt_decrypt( $cipher, $generatedKey, $encodedData, $cipherMode, $generatedIV );
echo "output (hex)" . bin2hex($output);`
但是我仍然不知道“计数”会去哪里。
非常感谢任何帮助。
最佳答案
下面模仿了 php 中的 openssl EVP_BytesToKey - 我遇到的唯一问题是正确获取 key 长度,因此目前将其固定为 32 字节(根据您的需要进行修改) iv 是从使用的密码中获取的。 (盐没有实现,但是很容易添加)
$arr = bytestokey($hash,5,"aes-256-cbc","sha1");
$plain = openssl_decrypt($encrypted, "aes-256-cbc", $arr["key"], $options=0, $arr["iv"]);
function bytestokey($data,$count,$cipher,$digest) {
$ivlen = openssl_cipher_iv_length($cipher);
$keylen = 32;
$hash = "";
$hdata = "";
while(strlen($hash) < $keylen+$ivlen) {
$hdata .= $data;
$md_buf = openssl_digest($hdata, $digest);
//
for ($i = 1; $i < $count; $i++) {
$md_buf = openssl_digest ( hex2bin($md_buf),$digest);
}
$hdata = hex2bin($md_buf);
$hash .= $hdata;
}
//
$key = substr($hash,0,$keylen);
$iv = substr($hash,$keylen,$ivlen);
//
return array('key' => $key, 'iv' => $iv);
}
关于php - PHP 中的 EVP_BytesToKey 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22060554/