У меня есть тестовый файл объемом 1 МБ, и я хочу расшифровать его, начиная с 500 КБ, а не с самого начала. Он не должен начинаться точно с 500 КБ файла, он может начинаться с начала любого фрагмента, если он не первый, я просто хочу узнать, как это сделать.
С помощью этого скрипта я могу расшифровать файл, если он начинается с 0 КБ.
$file = file_get_contents("file.dat");
$aeskey = base64_decode("sVv2g7boc/pzCDepDfV1VA==");
$iv = base64_decode("A5chWWE3D4cAAAAAAAAAAA==");
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'ctr', '');
mcrypt_generic_init($td, $aeskey, $iv);
echo mdecrypt_generic($td, $file);
Может ли кто-нибудь объяснить мне, если это возможно?
В Режим CTR, счетчик (128 бит для AES) шифруется для создания потока ключей, который затем XOR с открытым текстом или зашифрованным текстом. Обычно предполагается, что IV является 64-битным или 96-битным, а оставшиеся биты фактически устанавливаются в 0. Вызываются начальные 64 или 96-битные данное время.
Размер одноразового номера определяет, сколько данных можно зашифровать за один раз, не создавая многократную временную площадку: чем больше одноразовый номер, тем меньше безопасная длина сообщения, но также ниже вероятность коллизий двух одноразовых номеров, когда они генерируются случайным образом. Поскольку не указано, насколько велик одноразовый номер, многие фреймворки не ограничивают размер одноразового номера конкретным размером.
Вы можете использовать полный размер блока для одноразового номера в mcrypt.
Вы можете
Шаги 2-4 выполняются add
функция в следующем коде.
Допустим, у вас есть большой файл, но вы хотите расшифровать его из байта 512 (кратного размеру блока для простоты). Вы бы добавили 512/16 = 32 до IV.
Вот пример кода:
<?php
$d = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
$k = "k0k1k2k3k4k5k6k7"; // 16 byte AES key
$bs = 16; // 16 byte block size
$iv = mcrypt_create_iv($bs);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'ctr', '');
mcrypt_generic_init($td, $k, $iv);
$ct = mcrypt_generic($td, $d);
$dec_offset = 32;
$ct_slice = substr($ct, $dec_offset);
$iv_slice = add($iv, $dec_offset / $bs);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'ctr', '');
mcrypt_generic_init($td, $k, $iv_slice);
$d_slice = mdecrypt_generic($td, $ct_slice);
var_dump($d_slice);
function add($big_num_str, $to_add){
$big_num = str_split(strrev($big_num_str));
for($i = 0; $i < count($big_num) ; $i++){
$tmp = ord($big_num[$i]) + $to_add;
$big_num[$i] = $tmp % 256;
$to_add = floor( $tmp / 256 );
}
while($to_add){
$big_num[$i++] = $to_add % 256;
$to_add = floor( $to_add / 256 );
}
for($i = 0; $i < count($big_num) ; $i++){
$big_num[$i] = chr($big_num[$i]);
}
return strrev(implode('', $big_num) );
}
Выход:
строка (32) "101112131415161718191a1b1c1d1e1f"
Это также работает точно так же для расширения OpenSSL в PHP. Вот это код.
Конечно, это будет немного сложнее, если вы хотите получить фрагмент, который начинается не на границе блока. Вы должны начать блок раньше и удалить лишние байты.
Других решений пока нет …