问题
I've been trying to implement the exact same function in PHP as the one in C. However, I have not seen the exact same outcome. I think the problem is with the "count" or iteration that I still do not totally understand.
Function definition:
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)
Here is the link to the C function implementation: evp_key.c.
Here is what I found on Stack Overflow, which is close, but without the "count" that the author briefly mentioned: Encrypting data in Cocoa, decoding in PHP. The key lines as provided by user myztikjenz are here:
$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);`
However I still do not know where the "count" would go.
Any help is greatly appreciated.
回答1:
Below mimics the openssl EVP_BytesToKey in php - The only problem I have is to get the key length correctly so for now it is fixed to 32 bytes (amend to suit your needs) iv is get from the cypher used. (salt is not implemented, but easy to add)
$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);
}
来源:https://stackoverflow.com/questions/22060554/evp-bytestokey-implementation-in-php