2015-08-13 5 views
0

Я пытаюсь написать простой 2-х степенный класс шифрования с помощью mcrypt, чтобы узнать больше о шифровании, и все, кажется, работает нормально. Проблема, с которой я сталкиваюсь, заключается в получении ошибки PHP, указывающей, что параметр «IV должен быть до тех пор, пока размер блока», однако шифрование и дешифрование, похоже, работают. Является ли мое понимание значения IV неправильным? Любое толчок в правильном направлении было бы весьма полезным. Благодарю.IV Параметр должен быть до тех пор, пока размер блока, но шифрование/дешифрование все еще работает

Редактировать: Я на самом деле ошибаюсь, шифрование/дешифрование не работает, и я не уверен, почему.

Edit2: Хорошо, я понял, почему шифрование не работает (спасибо Роберту), но исходная проблема все еще существует.

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

?> 
+0

Вы должны определенно проверить 'mcrypt_enc_get_iv_size()' функция – Robert

+0

, где делать и установить «iv_size» я не могу найти его? – Robert

+0

Спасибо за этот улов, я сходил с ума, пытаясь понять, почему шифрование сломалось. Теперь, когда шифрование работает, я все еще получаю исходную ошибку «Параметр IV должен быть до тех пор, пока размер блока». Я отредактировал код, чтобы отразить это исправление. – Mike

ответ

1

Я думаю, что проблема в mcrypt_function()

Вы передаете хэшируются IV вместо IV создан mcrypt_create_iv(), поэтому размер отличается.

Вы можете получить правильный размер IV с функцией mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128 , 'cbc');

Правильная длина IV составляет 16 байт для Rijndael 128 (другой режим, чем ЕЦБ, ЕЦБ не использует 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); 
+0

Пожалуйста, исправьте меня, если я ошибаюсь. Поэтому для тестирования я удалил хэшированный iv и использовал обычно генерируемый IV, используя mcrypt_create_iv(). Затем я использовал mcrypt_get_iv_size() для генерации размера IV, который в этом случае равен 16. Когда я все это делаю, шифрование все еще работает, но я все равно получаю это же предупреждение. – Mike

+0

Я отредактировал свой ответ с помощью очень простого примера – Robert

+0

@ L337Man Ваш ключ длиной всего 26 символов. Он должен быть длиной 16, 24 или 32 байта. –

 Смежные вопросы

  • Нет связанных вопросов^_^