Новости

Шифрование больших файлов с помощью OpenSSL в PHP

Шифрование больших файлов с помощью OpenSSL в PHP

Шифрование больших файлов имеет свои особенности. Так, например, файл, размер которого превышает несколько сотен мегабайт не удастся зашифровать сразу весь — так как на это просто не хватит памяти. Поэтому в таких случаях файлы приходиться шифровать небольшими блоками — кусками.

В примере ниже показано как зашифровать большой файл с помощью OpenSSL в PHP.


<?php

// размер блока ("куска"), шифруемого файла
define('FILE_BLOCK_SIZE', 10240);

/**
 * @param  $source  Путь к шифруемому файлу + название самого файл
 * @param  $dest    Путь куда будет сохранен зашифрованный файл + название самого файла
 * @param  $key     Ключ шифрования
 */
function encrypt_file(string $source, string $dest, string $key)
{
    $cipher = 'aes-256-cbc'; // шифр
    $ivLenght = openssl_cipher_iv_length($cipher); // длина вектора инициализации
    $iv = openssl_random_pseudo_bytes($ivLenght); // генерирует псвевдо-случайную строку - вектор инициализации

    $fd_source = fopen($source, 'rb'); // открываем исходный файл в режиме бинарного чтения
    $fd_dest   = fopen($dest, 'w'); // открываем новый файл в режиме записи

    // записываем вектор инициализации в начало файла
    // он нам понадобиться при расшифровке
    fwrite($fd_dest, $iv);

    // читаем исходный файл пока не достигнем конца файла
    while ( !feof($fd_source) ) {
        // из исходного файла берем "кусок"
        $plaintext = fread($fd_source, $ivLenght * FILE_BLOCK_SIZE);
        // шифруем этот "кусок"
        $ciphertext = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        // ????
        //$iv = substr($ciphertext, 0, $ivLenght);

        fwrite($fd_dest, $ciphertext);
    }

    // закрываем файлы
    fclose($fd_source);
    fclose($fd_dest);
}

/**
 * @param  $source  Полный путь к зашифрованному файлу
 * @param  $dest    Путь, куда будет сохранен расшифрованный файл + название самого файла
 * @param  $key     ключ шифрования
 */
function decrypt_file(string $source, string $dest, string $key)
{
    $cipher = 'aes-256-cbc';
    $ivLenght = openssl_cipher_iv_length($cipher);

    $fd_source = fopen($source, 'rb');
    $fd_dest   = fopen($dest, 'w');

    // извлекаем сохраненный вектор инициализации из начала файла
    $iv = fread($fd_source, $ivLenght);

    // по "кусочкам" расшифровываем файл
    while ( !feof($fd_source) ) {
        $ciphertext = fread($fd_source, $ivLenght * (FILE_BLOCK_SIZE + 1));
        $plaintext = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        //$iv = substr($plaintext, 0, $ivLenght);

        fwrite($fd_dest, $plaintext);
    }

    fclose($fd_source);
    fclose($fd_dest)  ;
}

Вызываем так:


<?php

    $src_file  = "новый_видеокурс.avi";
    $dest_file = "новый_видеокурс.avi.encrypted";
    $key = "самыйсильныйпароль";

    // зашифровываем
    encrypt_file($src_file, $dest_file, $key);

    // расшифровываем
    decrypt_file($src_file, $dest_file, $key);


Источник

Статьи по теме

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Back to top button