PHP中的EVP_BytesToKey实现

时间:2014-02-27 06:19:13

标签: php c cryptography php-extension

我一直在尝试在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);`

但是我仍然不知道“计数”会去哪里。

非常感谢任何帮助。

1 个答案:

答案 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);
        }