【问题标题】:IV Parameter must be as long as the block size, but encryption/decryption still worksIV 参数必须与块大小一样长,但加密/解密仍然有效
【发布时间】:2015-11-06 12:57:07
【问题描述】:

我正在尝试使用 mcrypt 编写一个简单的 2 路加密类,以了解有关加密的更多信息,并且一切似乎都运行良好。我遇到的问题是我收到一个 PHP 错误,指出“IV 参数必须与块大小一样长”但是,加密和解密似乎都在工作。我对 IV 大小的理解不正确吗?任何朝着正确方向的推动将不胜感激。谢谢。

编辑:我实际上是错的,加密/解密不起作用,我不确定为什么。

Edit2:好的,我知道为什么加密不起作用(感谢 Robert),但原来的问题仍然存在。

<?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);

?>

【问题讨论】:

  • 你应该明确检查mcrypt_enc_get_iv_size() function
  • 你在哪里设置 'iv_size' 我找不到?
  • 感谢您的发现,我正疯狂地试图找出加密失败的原因。现在加密工作正常,我仍然收到原始错误“IV 参数必须与块大小一样长”。我已经编辑了代码以反映该修复。

标签: php encryption mcrypt


【解决方案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);

【讨论】:

  • 如果我错了,请纠正我。因此,为了测试,我放弃了散列 iv 并使用 mcrypt_create_iv() 使用通常生成的 IV。然后我使用 mcrypt_get_iv_size() 生成 IV 的大小,在这种情况下为 16。当我执行所有这些操作时,加密仍然有效,但我仍然收到相同的警告消息。
  • @L337Man 您的密钥只有 26 个字符长。它的长度必须为 16、24 或 32 字节。
  • RIJANDEL 128 为 16 个字节
  • @Artjom B 哦,好吧,让我试一试。你能解释一下为什么会这样(或提供链接),还是只是由 php 定义?
  • @Robert 如果我使用 RIJANDEL 256 会怎样?
猜你喜欢
  • 2015-05-12
  • 2014-07-18
  • 2016-06-22
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
相关资源
最近更新 更多