Как использовать режим шифрования CBC в PHP

Я пытаюсь зашифровать строку длиной 50-150 символов с помощью AES в режиме, отличном от ECB (из-за проблем с безопасностью). Я написал класс шифрования и могу отлично шифровать/дешифровать в режиме ECB, однако, когда я переключаюсь в режим CBC, CTR или OFB, мне не удается вернуть исходный открытый текст.

Источник:

define('DEFAULT_ENCRYPTION_KEY', 'asdHRMfjkahguglw84tlrogl9y8kamaFDaufasds');

class Encryption
    {
    private $mode   = 'ctr';
    private $algo   = 'rijndael-128';
    private $td     = null;

    function __construct($key = DEFAULT_ENCRYPTION_KEY)
        {
        $this->td = mcrypt_module_open($this->algo, '', $this->mode, '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_DEV_URANDOM);
        $key = substr($key, 0, mcrypt_enc_get_key_size($this->td));
        mcrypt_generic_init($this->td, $key, $iv);
        }

    public function encrypt($data)
        {
        $encrypted_data = mcrypt_generic($this->td, $data);
        return $encrypted_data;
        }   

    public function decrypt($data)
        {
        $decrypted_data = mdecrypt_generic($this->td, $data);
        $decrypted_data = rtrim($decrypted_data, "\0");
        return $decrypted_data;
        }

    function __destruct()
        {
        mcrypt_generic_deinit($this->td);
        mcrypt_module_close($this->td);
        }

    }

$crypt1 = new Encryption();
$enc = $crypt1->encrypt('hello world');

$crypt2 = new Encryption();
$dec = $crypt2->decrypt($enc);

echo $dec;

Возвращаемое значение $dec не равно «привет, мир».

Любые идеи?


person Matic    schedule 11.06.2009    source источник


Ответы (1)


Похоже, вы отбрасываете вектор инициализации $iv. Вам нужно знать IV, чтобы успешно расшифровать сообщение. IV не секрет; обычно он передается вместе с зашифрованным текстом в каком-то обертывающем формате.

Поскольку нет обратной связи от блока к блоку, ECB не нужен вектор инициализации. Но режимам цепочки блоков нужны некоторые данные для «запуска» режима шифрования.

person erickson    schedule 11.06.2009
comment
Хм, но если я использую такой класс, IV должен остаться прежним: $crypt1 = new Encryption(); $enc = $crypt1-›encrypt('привет, мир'); $dec = $crypt1->decrypt($enc); Тем не менее, он по-прежнему создает случайный открытый текст в качестве вывода. - person Matic; 11.06.2009
comment
Это предполагает, что IV хранится где-то внутри $td, что не всегда так. Было бы трудно утверждать, что это хороший дизайн, поскольку в большинстве приложений один и тот же объект шифра вряд ли зашифрует и расшифрует одно и то же сообщение, а при шифровании нескольких сообщений для каждого сообщения следует использовать разные IV. - person erickson; 11.06.2009