Случайный ключ шифрования Openssl и IV-Хранилище в БД
Я много читал о шифровании и знаю, что с php 7 появилось много нового. Я пишу две функции (шифрование и расшифровка) для хранения зашифрованных данных в моей бд.
Я понимаю, как работает функция openssl, но мне интересно, правильно ли я храню ее в своей бд или мне следует сказать надежно. Мой код выглядит следующим образом:
function wm_encryptString($string) {
$method = 'aes-256-xts';
$key = random_bytes(16);
$iv = random_bytes(16);
$cipherText = openssl_encrypt($string, $method, $key, 0, $iv);
$cipherText = $key.$iv.$cipherText;
$cipherText = base64_encode($cipherText);
return $cipherText;
}
function wm_decryptString($cipher) {
$cipher = base64_decode($cipher);
$method = 'aes-256-xts';
$key = substr($cipher, 0, 16);
$iv = substr($cipher, 16, 16);
$cipher = substr($cipher, 32);
$readableText = openssl_decrypt($cipher, $method, $key, 0, $iv);
return $readableText;
}
Когда я запускаю эти две функции, он шифрует и расшифровывает просто отлично. Мой конкретный вопрос заключается в том, использует ли случайные байты для генерации ключа и IV безопасно, и добавление его к зашифрованному тексту безопасно для хранения в БД? Я храню некоторую конфиденциальную информацию и хочу убедиться, что она надежно зашифрована.
Мой второй вопрос: я знаю, что могу зашифровать строки с помощью этой функции, но могу ли я зашифровать большие двоичные объекты с помощью этой же функции? Я храню некоторые документы в своей бд (я знаю, что многие из вас скажут никогда не хранить документы в бд, но я использую бд, потому что я храню только несколько документов, менее 100, и это создает резервную копию проще). Могу ли я зашифровать большой двоичный объект/файл с помощью этой же функции?
Буду признателен за любые отзывы, так как я хочу, чтобы мое приложение было максимально безопасным. Примечание. Я знаю, что должен принять гораздо больше мер безопасности, чтобы обеспечить безопасность моего приложения, мой вопрос касается шифрования. Спасибо.
2 answers
Случайные байты для ключа и IV хороши, префикс IV к зашифрованным данным хорош, оба варианта безопасны.
Шифрование основано на байтах, оно не заботится о какой-либо кодировке, большом двоичном объекте или ином. Для текста получите байты в формате utf-8.
Почему вы выбрали режим XTS, он обычно используется для шифрования диска? Смотрите Вы Не хотите XTS. Как правило, режим CBC или CTR является правильным выбором. Обратите внимание, что с помощью CBC не возвращайте ошибки добавления, с CTR никогда не используйте один и тот же IV (начальное значение счетчика) и ключ – легко ошибиться.
Наконец, как вы планируете защитить ключ(ы) шифрования? Это самая трудная часть.
Поскольку ключ хранится рядом с зашифрованным текстом, эта схема не обеспечивает никакой реальной безопасности. Скорее, это запутывание. К нему применим термин безопасность через неизвестность.
Имейте в виду, что ключ - это единственная часть, которую нужно держать в секрете. Это известно как принцип Керкгоффа. Обычно предполагается, что злоумышленник может прочитать исходный код вашего кода на стороне сервера, когда сервер взломан. В этом случае это почти невозможно разработать схему, в которой ключ хранился бы в секрете от злоумышленника (подумайте об аппаратном модуле безопасности).
Конечно, существуют различные типы нарушений. Вам может повезти, если злоумышленник получит доступ только к записям базы данных, фактически не получив доступа к оболочке на веб-сервере. Это может произойти, когда веб-приложение неправильно аутентифицирует и авторизует запросы в дополнение к ошибке, при которой из базы данных может быть запрошена произвольная информация (подумайте Инъекция SQL).
Даже в этом случае злоумышленник может получить представление о том, как зашифрованы данные, просто взглянув на данные (статистика длины всех зашифрованных текстов является хорошей подсказкой).