我一直在尝试在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);`
但是我仍然不知道“计数”会去哪里。
非常感谢任何帮助。
答案 0 :(得分:3)
在下面模仿php中的openssl EVP_BytesToKey-我唯一的问题是正确获取密钥长度,因此目前它固定为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);
}