IV参数必须与块大小一样长,但加密/解密仍然有效

时间:2015-08-13 13:55:26

标签: php encryption mcrypt

我正在尝试使用mcrypt编写一个简单的2路加密类来了解有关加密的更多信息,而且一切似乎都运行正常。我遇到的问题是我收到一个PHP错误说明" IV参数必须和块大小一样长#34;但是,加密和解密似乎都有效。我对IV大小的理解不正确吗?任何正确方向的推动都将非常感激。感谢。

编辑:我其实是错的,加密/解密无效,我不确定原因。

编辑2:好吧,我弄清楚加密为什么不起作用(感谢罗伯特),但原始问题仍然存在。

<?php

ini_set("display_errors", 1);

class IDBCrypt {

    private $iv_size, $hash_type, $hash_size, $hash_key, $encryption_key;

    const SECRET_KEY = "Ep8+NFPfybsJn26ZFyPn213WTI";
    const HASH_KEY = "mU2YjBiZDVmYjBiOWUyNmE";
    const HASH_TYPE = "sha256";
    const HASH_SIZE = 64;

    /** 
      * For SHA256 hashing algorithm
      * each digit requires 4 bits of
      * memory. This means that you need
      * 64 digits to represent a 256 bit 
      * hash, thereby making the size of 
      * a hash generated with this algorithm
      * 256 bits, with a length of 64
      */

    function __construct() {

        /* Constructor */

    }

    function encrypt( $data ) {

        // Generate an IV to encrypt with
        $iv = mcrypt_create_iv( self::HASH_SIZE, MCRYPT_RAND );
        $hashed_iv = hash_hmac( self::HASH_TYPE, $iv, self::HASH_KEY );

        // echo $iv ."<br><br>";

        // Encrypt plain text
        $cipher_text = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, self::SECRET_KEY, $data, MCRYPT_MODE_CBC, $hashed_iv );

        // Base64 encode and salt the data
        $cipher_text_64 = base64_encode( $hashed_iv . $cipher_text );

        return $cipher_text_64;

    }

    function decrypt( $data ) {

        // Base64 decode the cipher text
        $ciphertext_dec = base64_decode( $data );

        // retrieves the IV/salt from the cipher text
        $iv_dec = substr( $ciphertext_dec, 0, self::HASH_SIZE );

        // retrieves the cipher text (everything except the $iv_size in the front)
        $ciphertext_dec = substr( $ciphertext_dec, self::HASH_SIZE );

        $plaintext = mcrypt_decrypt( MCRYPT_RIJNDAEL_128, self::SECRET_KEY, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec );

        return $plaintext;

    }

}

$crypt = new IDBCrypt();

$string = $crypt->encrypt("Greetings from encryption and beyond");

echo $string . "<br>";

echo $crypt->decrypt($string);

?>

1 个答案:

答案 0 :(得分:1)

我认为mcrypt_function()

中存在问题

你传递散列IV而不是由mcrypt_create_iv()创建的IV,这就是尺寸不同的原因。

您可以使用函数mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128 , 'cbc');

获得正确的IV大小

对于RIJNDAEL 128,IV的适当长度是16字节(除ECB之外的其他模式,ECB不使用IV)。

所以你可以改变(因为你通过了64)

$iv = mcrypt_create_iv( self::HASH_SIZE, MCRYPT_RAND );

$iv = mcrypt_create_iv( 16, MCRYPT_RAND );

它会起作用。

编辑:

检查这个简单的例子。当然需要删除填充

$text ='asdf';
$key = 'Ep8+NFPfybsJn26ZFyPn213WTI';
$iv = mcrypt_create_iv( 16, MCRYPT_RAND );
$cipher_text = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);

echo mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $cipher_text , MCRYPT_MODE_CBC, $iv);