Вы стали шпионом. Как защитить свои данные?

8 ноября 2026

Вы стали молодым шпионом, теперь ваш арсенал состоит из телефона, ноутбука и быстрых ног. Пользуясь благами электронно-вычислительной техники, вы решаете хранить «тайную шпионскую информацию»™ на своём ноутбуке. С телефона не очень удобно читать 400-страничный отчёт о суперсекретной программе YKeyScore, который вы собираетесь слить своим работодателям…

Или вы просто параноик специалист по информационной безопасности, хотеть защитить свои данные — это нормально.

Начните с модели угроз

Для того чтобы ответить на вопрос «Как защитить свои данные?», надо прежде всего выбрать модель угроз. Надо продумать, от кого вы собираетесь защищаться, кто потенциальный нарушитель, какие у него возможности и что конкретно защищать. Пример: у вас есть ноутбук с рабочими документами и младший брат, который очень хочет играть на нём в пиратский майнкрафт. Вы уходите из дома и ноутбук остаётся с младшим братом 1 на 1. Для защиты от такого злостного нарушителя хватит и обычного пароля на аккаунт.

А если играем по-серьёзному и ваш атакующий достаточно прошарен в теме ИБ и в компах? Представим: у вас украли ноутбук. Злоумышленник может извлечь диск, загрузиться с флешки в WinPE и прочитать все файлы. А ещё он может загрузиться в Kon-Boot — эта программа позволяет загрузиться в обход паролей пользователя. И если ваши влажные файлы (например, 2 тысячи картинок Пикси) никак не зашифрованы, то злоумышленник может их с лёгкостью украсть.

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

Слово «физических» я выделил жирным не просто так. Порой можно прочитать истории, как люди шифровали свои сервера. В некоторых ситуациях это, конечно, имеет смысл, но только если физический вектор атаки — ваш потенциальный сценарий. Полное шифрование диска никак не защитит от удаленной атаки, напротив, если злоумышленник получит рут, то он сможет за секунду уничтожить абсолютно все данные на сервере, просто стерев заголовок, но об этом позже.

Шифрование файлов и шифрование диска

В контексте защиты файлов есть два основных подхода к защите информации — File Based Encryption (FBE) и Full Disk Encryption (FDE). Первый способ шифрует на уровне отдельных файлов и папок, а не всего раздела или накопителя. Второй способ, исходя из названия, шифрует диск (раздел) целиком, включая операционную систему, временные файлы и все данные.


FBE: Android и EFS в Windows

Начнём с File Based Encryption, потому что с ним вы, скорее всего, уже встречались. Возможно, прямо сейчас вы читаете с устройства, данные которого зашифрованы именно этим методом.

FBE в Android

С 2019 года и Android 10 все новые устройства обязаны использовать FBE, хотя сама технология была реализована ещё с 7-го Android. В Android оно реализуется с помощью механизма ядра fscrypt. Полный разбор этой технологии в контексте Android с TEE (Trusted Execution Environment) потянет на отдельную статью, так что надеюсь на фидбек, если будет интересно.

А мы возвращаемся к FBE на десктопе. Windows ещё с 2000-й версии поддерживает Encrypting File System (EFS) — систему шифрования данных, реализующую шифрование на уровне файлов в файловой системе NTFS.

Активация EFS в старых версиях Windows

Когда вы нажимаете галочку «зашифровать», Windows генерирует случайный ключ — File Encryption Key (FEK), которым в дальнейшем будет шифровать содержимое файлов с помощью AES-256 в режиме CBC.

Что такое AES и CBC?

AES (Advanced Encryption Standard) — популярный алгоритм симметричного блочного шифрования. Симметричный означает, что используется один ключ, а блочный — что алгоритм обрабатывает данные не по одному байту, а порциями фиксированного размера. В AES это блоки по 128 бит (16 байт).

Ключ для AES должен быть тоже фиксированного размера, например 128, 192 и 256 бит. Чем длиннее ключ, тем сложнее его взломать:)

Но ведь наши пароли редко когда составляют ровно 16, 24 и 32 символа. Поэтому перед тем как шифровать AES, ваши пароли прогоняют через «функцию формирования ключа» (Key Derivation Function, KDF). Эта односторонняя функция превращает ваш короткий пароль в строку определённой длины. Дальше в статье будет более подробно рассмотрена тема KDF.

У AES бывают разные режимы работы. CBC — только один из режимов работы блочного шифра. Данные разбиваются на блоки по 128 бит. Первый блок перед шифрованием объединяется (складывается по операции XOR) со специальным случайным числом — вектором инициализации (IV). Второй блок сначала XOR-ится с результатом шифрования предыдущего блока и только потом шифруется ключом. Процесс повторяется до конца сообщения.

Если использовать простые режимы, такие как ECB (Electronic Code Book), то одинаковые блоки текста дадут одинаковый шифр. Что это означает, проще всего визуализировать.

Пример уязвимости AES ECB

В старых версиях Windows использовались менее безопасные алгоритмы, такие как XDES и 3DES. Полученный FEK шифруется с помощью публичного ключа пользователя (RSA-2048, на современных версиях используют эллиптические кривые). Что ещё за публичный ключ пользователя? На локальном устройстве при активации EFS система создаёт самоподписанный сертификат. Приватный ключ зашифрован с помощью DPAPI (Data Protection API) Windows. DPAPI использует мастер-ключ пользователя, который, в свою очередь, зашифрован с помощью пароля пользователя (kdf: pbkdf2). Таким образом, шифрование файла или папки фактически привязывается к паролю от вашего пользователя.

Затем EFS не меняет структуру самого файла и ничего в тело не дописывает. Все служебные данные записываются в метаданные NTFS. В MFT (Master File Table) записывается DDF (Data Decryption Field) — тут хранится FEK, зашифрованный с помощью RSA. Ну и SID пользователя и хэш его сертификата.

Использовать EFS, конечно, удобно, но крайне небезопасно. Для хеширования паролей в Windows используется NTLM, что, по сути, md4 (даже не md5) без соли от UTF-16 строки пароля. Можем забыть про этот алгоритм, в статье он только для практического примера реализации FBE.


Шифрование отдельных файлов с GPG

Если хочется зашифровать папку с любимыми фотографиями Пикси с помощью FBE, то можно использовать GPG (GNU Privacy Guard), который по умолчанию использует AES 256 в режиме CFB (по стандарту OpenPGP). Для этого GPG генерирует сессионный ключ с помощью криптографически стойкого генератора случайных чисел — CSPRNG. Этот ключ уникален для каждой сессии. Затем GPG использует собственную KDF-функцию для преобразования вашего пароля — S2K (String to Key) в режиме Iterated and Salted. Это означает, что ваш пароль прогоняется через хэш-функцию много-много раз, усложняя её брутфорс. Результат многократного хеширования и есть мастер-ключ, которым шифруется сессионный ключ. Результат записывается в блок Symmetric-Key Encrypted Session Key (SKESK). Сами данные сжимаются и шифруются с помощью сессионного ключа. Для контроля целостности на старом режиме CFB обязательно создаётся Modification Detection Code (MDC) — SHA-1-хеш от plain-текста. Если используются новые алгоритмы, то при использовании AEAD защита от изменений встроена в сам алгоритм шифрования на уровне математики. В результате мы получаем зашифрованный gpg-файл.


Но удобно ли раз за разом расшифровывать файл, распаковывать картинки и делать кучу ненужных операций, если очень хочется пару раз в день посмотреть на фотокарточки? GPG для этого крайне неудобен, хоть и не вызывает больших накладных расходов в плане увеличения размера.

Зашифрованные контейнеры VeraCrypt

Что же делать, чтобы безопасно зашифровать файлы, так ещё и удобно с ними работать? На помощь приходят зашифрованные контейнеры. Самой популярной для этого программой является VeraCrypt с очень интересной историей.

Занимательная история VeraCrypt

Жил-был Пол Ле Ру. Он вырос в приёмной семье в Африке. В 13 лет он купил свой первый компьютер, а в 16 уже был впервые арестован за распространение порнографии, что было серьезным преступлением в ЮАР того времени, но дело замяли.

Он бросил школу, самостоятельно освоил годовую программу курсов по программированию всего за восемь недель. В 18 лет он переезжает в Великобританию, где устроился работать программистом в банки и коммерческие фирмы. В этот период он увлёкся движением шифропанков — они считали, что шифрование — это единственное средство защиты свободы личности от тотального контроля государств.

Он в одиночку разрабатывает программу E4M (Encryption for the Masses), для своего времени (1999) это был революционный продукт. Программа позволяла шифровать не просто отдельные файлы, а целые разделы жёсткого диска «на лету». На лету означает, что после ввода верного пароля у вас появлялся раздел, будто диск D:, с которым вы просто работаете в проводнике или в любой другой программе, но физически на диске данные зашифрованы.

Но программа стала популярной в узких кругах не из-за этого. E4M поддерживал Deniable Encryption — программа позволяла создавать скрытые зашифрованные контейнеры. Если пользователя заставляли выдать пароль под принуждением, то он мог ввести ложный пароль. Программа открывала доступ к безобидным файлам, а существование секретного слоя данных было технически невозможно доказать.

И такая революционная программа была с открытым исходным кодом, чтобы любой желающий мог убедиться, что в программе нет бэкдоров. В манифесте к E4M Ле Ру открыто заявлял, что правительства массово внедряют системы слежки, и его цель — дать обычным гражданам абсолютную защиту частной жизни.

Однако в начале 2000-х Ле Ру внезапно исчез из публичных криптографических форумов. Ему были нужны деньги, а E4M по своей задумке денег не приносил.

Однако в феврале 2004 года анонимная группа разработчиков выложила в открытый доступ программу TrueCrypt. Она была основана на исходном коде E4M. Неизвестно, кто стоял за анонимными TrueCrypt Team, однако многие считают, что Пол Ле Ру входил в эту «тайную организацию».

TrueCrypt стал мировым стандартом. Им пользовались все: от правозащитников до хакеров и спецслужб. И даже сам Пол Ле Ру, когда он… начал строить свою наркоимперию.

Да, наш гениальный разработчик решил торговать наркотиками. В 2004 году он создал RX Limited. Это была сеть из сотен сайтов, которая продавала американским гражданам рецептурные препараты (в первую очередь мощное обезболивающее трамадол, а также сому и виагру) в обход законов США. Всё было автоматизировано, и система приносила огромные деньги. Чистая прибыль Ле Ру была 5–6 миллионов долларов в неделю. Он начал инвестировать в кокаин и метамфетамин и даже создавать свою армию. Для устранения конкурентов он нанимал бывших военных и спецназовцев западных стран. Так родился самый настоящий картель.

И, разумеется, его поймали. Ещё в 2007 году УБН обратили внимание на огромный объём подозрительных посылок с обезболом, которые доставлялись американцам на дом. Они вышли на RX Limited, но из-за того, что сервера были зашифрованы TrueCrypt, они не могли взломать систему даже физически. Его финансовый след начали плотно отслеживать и арестовывать курьеров. Ле Ру стал параноиком и начал жестоко устранять своих людей за малейшие подозрения в воровстве или предательстве. Одним из его доверенных лиц по логистике наркотиков был пилот по имени Феликс «Джек» Клауссен. Опасаясь, что Ле Ру убьет его следующим (в картеле уже произошла серия казней сотрудников), Клауссен решил спасти свою жизнь. Он тайно связался с УБН и согласился стать информатором. В 2012 году Ле Ру прилетел в Либерию на фальшивые переговоры с колумбийским картелем, где его и взяли с поличным, когда он уже достаточно наговорил на скрытую камеру. Когда понял, что дело плохо, он решает сдать всех и стать живой приманкой. Так поймали и главу его карательного отряда. Благодаря его сговорчивости он получил всего 25 лет тюрьмы.

Такой вот интересный человек стоял за разработкой TrueCrypt, хотя сам он отрицал эту связь, что неудивительно.

TrueCrypt продолжал своё развитие и после компрометации Ле Ру. В 2013 году собрали 60 тысяч долларов на аудит безопасности кода TrueCrypt 7.1a, аудит не выявил никаких бэкдоров или серьезных уязвимостей.

Однако 28 мая 2014 года внезапно на сайте TrueCrypt появилось предупреждение, что «Использование TrueCrypt больше не безопасно, поскольку оно содержит неисправленные уязвимости» с гайдом, как мигрировать на BitLocker. Разработка была прекращена. До сих пор доподлинно неизвестно, что же такое случилось. Мнение автора: личность разработчиков могли раскрыть влиятельные люди (ну или спецслужбы) и под давлением они экстренно покинули разработку проекта. Призыв переходить на проприетарный и закрытый BitLocker намекает на то, что дело пахнет керосином.

Но проект не умер. Ещё до закрытия TrueCrypt французский программист Мунир Идрасси и его компания IDRIX создали форк под названием VeraCrypt. Автор сразу же начал усиление безопасности, увеличение количества итераций KDF и т. д. и т. п. Проект VeraCrypt активно обновляется до сих пор и всё так же успешно проходит аудиты безопасности (последний полноценный на моей памяти был в 2020 году немцами).

Как работают зашифрованные контейнеры для обычных пользователей? У вас есть зашифрованный файл, который вы можете хранить где угодно: на флешке, на диске, в облаке. С помощью VeraCrypt вы открываете (монтируете) этот зашифрованный контейнер как самый обычный диск D:, будто вы подключили обычную флешку. Вы работаете с этим диском, читаете и записываете файлы, а VeraCrypt прямо «на лету» делает операции шифрования. Для хранения 2000 фотографий Пикси это, пожалуй, самый безопасный и рациональный вариант.

Как создаются контейнеры и обеспечивается безопасность VeraCrypt-контейнеров? Вы выбираете, где сохранить файл и какой у него размер, затем VeraCrypt собирает энтропию посредством того, что заставляет двигать мышкой в рамках окна. Почему? Встроенные генераторы случайных чисел в операционных системах могут содержать бэкдоры или быть небезопасными. Использовать для этого процессор? В процессорах AMD Ryzen на архитектуре Zen 5 в ранних партиях нашли ошибку, в результате которой инструкция RDSEED для генерации случайных чисел на основе аппаратных шумов просто возвращала 0. Разработчики решили не полагаться на один источник энтропии, а использовать несколько одновременно, программа считывает координаты мыши и точное время каждого микродвижения, использует аппаратные генераторы случайных чисел и различные системные API. Затем весь пул энтропии непрерывно хешируется с помощью выбранного алгоритма, например SHA-512, и, когда программе нужны случайные байты, она извлекает их из этого пула. Такая схема гарантирует, что при компрометации одного из «источников случайности» ключи не будут скомпрометированы.

Генерируется случайная соль, чтобы два разных контейнера с одинаковыми паролями имели разные ключи шифрования заголовков. Затем генерируется мастер-ключ, которым будут шифроваться данные. Длина мастер-ключа зависит от алгоритма. Например, для AES в режиме XTS (самый популярный режим работы AES для работы «на лету») VeraCrypt вынужден по стандарту генерировать два ключа по 256 бит. VeraCrypt также поддерживает «каскад» ключей, например, AES-Twofish-Serpent. Второй ключ XTS называется Tweak: он нужен для векторов смещения, чтобы привязать шифрование к физическим координатам секторов на диске.

Пароль, соль и функция формирования ключа

Затем VeraCrypt берёт пароль пользователя (+ опционально файл-ключи) и соль. Это прогоняется через функцию формирования ключа (Key Derivation Function, KDF) — это алгоритм, который принимает входной секрет и превращает его в один или несколько криптографически стойких ключей заданной длины. Заданная длина нужна для алгоритмов шифрования, например, AES поддерживает ключи длиной 128, 192 и 256 бит. KDF также нужен для усложнения брутфорса пароля, потому что обычный хеш считается за микросекунды. Есть множество алгоритмов KDF, самым безопасным сейчас считается argon2 — победитель соревнования Password Hashing Competition (2015).

Дополнительно про файл-ключи хочу добавить необычную для программ шифрования функцию — поддержку EMV как второго фактора. Если у вас есть ноутбук, который имеет слот для смарт-карт, например ThinkPad, то вы можете привязать расшифровку контейнера к своей обычной банковской карте, которая, по идее, всегда с собой и не вызывает подозрений.

Безопасным он считается за счет своей устойчивости к атакам с аппаратным ускорением и защите от атак по сторонним каналам. Аппаратным ускорением я написал не просто так, хакеры используют как мощные пулы видеокарт, так и специализированные ASIC-и для подбора паролей. У видеокарт и ASIC-ов, конечно, много ядер, но у каждого ядра очень мало собственной памяти, поэтому режим argon2d специально использует много памяти для генерации ключа (memory-hard).

При компрометации устройства злоумышленники могут измерять время ответа системы или даже тепловыделение процессора, чтобы понять, какие участки памяти считываются (один из многих возможных вариантов атаки по сторонним каналам). Поэтому в режиме Argon2i все операции с памятью выполняются в фиксированном порядке, не зависящем от пароля. Время выполнения функции всегда одинаково, поэтому атакующий не сможет извлечь из колебаний времени полезной информации.

Создатели Argon2 взяли и объединили эти два режима argon2i и argon2d под названием argon2id, который берёт лучшее из обоих режимов работы. Argon2id считается современным стандартом.

Благодаря тому, что я пишу эту статью, я узнал, что недавно в VeraCrypt добавили поддержку этого замечательного алгоритма, после написания пойду переводить kdf своих контейнеров с Blake2s на Argon2id:)

С какими параметрами VeraCrypt прогоняет KDF? Это тоже может выбрать пользователь посредством PIM — Personal Iterations Multiplier (например, 500000 итераций sha-512, у argon2 ситуация сложнее, там несколько параметров).

Заголовок и монтирование контейнера

Итак, мы получили ключ шифрования заголовка. В этом заголовке в зашифрованном виде будет храниться мастер-ключ, которым шифруются данные. Размер заголовка — 64 КБ. Первые 64 байта — случайная соль, которая остаётся в открытом виде. С 64-го байта до конца 64-килобайтного блока все шифруется ключом шифрования заголовка.

Заголовок у нас есть, остаётся только создать файл. VeraCrypt посредством низкоуровневых API ОС, где запущен, создаёт файл, первые 64 КБ — заголовок. Затем в конец файла записывается такой же запасной заголовок в 64 КБ. Он нужен на случай, если некоторые секторы диска будут повреждены. Опционально для безопасности VeraCrypt затирает пространство между первым и вторым заголовком случайными данными. Это нужно для:

  1. Удаления старых данных (актуально для HDD)

  2. Маскировки скрытого раздела — необходимо для plausible deniability, то есть правдоподобного отрицания. Если бы пустой контейнер заполнялся нулями, то при создании скрытого раздела на диске чётко выделялась бы зона со случайными данными (скрытый контейнер) на фоне нулей. Заполнение шумом делает невозможным доказательство существования скрытых данных внутри свободного пространства. При этом варианте перезапись пустого места не опциональна.

Если вы используете plausible deniability и у вас SSD, то рекомендуется не убирать галочку в настройках VeraCrypt с использованием команды TRIM. TRIM — команда контроллеру SSD, чтобы физически разрядить незанятые ячейки памяти. С одной стороны, это позволяет надежно удалить файлы без необходимости перезаписи, с другой — скрытый раздел можно обнаружить по этим пустым блокам.

Финально, когда контейнер создан, VeraCrypt монтирует созданный файл как блочное устройство, например D:, он создаёт файловую систему. Операционная система может даже не знать, что это на самом деле зашифрованный файл, ей в целом-то пофиг. Шифрованием «на лету» занимается драйвер VeraCrypt, который в реальном времени перехватывает сектора, шифрует/расшифровывает их и пишет в файл. Шифрование осуществляется с помощью мастер-ключа, который хранится в оперативной памяти.

Теперь вы примерно понимаете архитектуру работы VeraCrypt и знаете, как она защищает ваши фотографии с Пикси.

Следы вне контейнера и шифрование системы

Но внезапно ваш друг попросил попользоваться ненадолго компьютером и каким-то образом узнал, что вы на нём смотрели фотографии Пикси (привет, syonkaio, кстати). Но как? Неужели он взломал ваш контейнер VeraCrypt? Вы ведь все так надежно зашифровали…

Но друг даже не планировал взламывать контейнер. Если вы используете ОС Windows, то перед тем как открыть фотографию в проводнике, этот самый проводник сделает её миниатюру для предпросмотра. И эти миниатюры сохраняются на диск в незашифрованном виде. Ему было достаточно прочитать базу данных thumbcache.db в %LOCALAPPDATA%\Microsoft\Windows\Explorer, где будут находиться все картинки Пикси в небольшом разрешении.

И это не какая-то теоретическая атака. Таким образом форензики ФБР находили доказательства просмотра CSAM в thumbs.db, несмотря на уничтоженный носитель.

Но мы-то не собираемся нарушать закон, мы хотим обезопасить свои данные и не допустить утечки метаданных о файлах из контейнера. Но невозможно учесть всевозможные способы, которые уже будут граничить с удобством использования. Поэтому для защиты данных существует полнодисковое шифрование — FDE (Full Disk Encryption). Таким образом все данные и операционная система будут зашифрованы без исключений. На диск все будет писаться только в зашифрованном виде.

И VeraCrypt поддерживает такой режим работы, он позволяет зашифровать системный раздел. Пароль для расшифровки системы необходимо вводить каждый раз при включении. В момент работы устройства ключи шифрования хранятся в оперативной памяти. Стоит выключить компьютер и без пароля содержимое диска — просто цифровой мусор.

Помимо этого VeraCrypt поддерживает даже создание скрытой операционной системы. Вводишь один пароль — грузится одна система. Вводишь другой — другая. Реализовано это посредством двух разделов: 1 раздел — обычный с нормальным паролем. 2 раздел — в hidden находятся данные ОС, а в outer — потенциально ложные данные. Однако такое проще заподозрить по причине того, что мало кто будет постоянно сидеть на «внешней» операционной системе + это требует наличия сразу двух зашифрованных разделов. Зачем кому-то иметь 2 зашифрованных раздела с двумя разными паролями?

Подытожим: VeraCrypt — это крутая открытая и кросплатформенная программа для создания зашифрованных контейнеров и дисков с надежными алгоритмами. Но шифрование системного раздела VeraCrypt поддерживает только на Windows.


А что если вы хотите использовать не Windows с телеметрией, а Linux?

OpSec level: infinity

LUKS2 и шифрование диска в Linux

Для шифрования дисков в Linux принято использовать LUKS (Linux Unified Key Setup) — это спецификация шифрования дисков/разделов. Точно так же, как VeraCrypt, он поддерживает шифрование «на лету» и современные KDF алгоритмы по умолчанию (argon2).

Небольшая палка в огород VeraCrypt: по какой-то причине до сих пор по умолчанию предлагает SHA-512 в качестве KDF по умолчанию.

Заранее небольшое уточнение: LUKS — это только спецификация, как должно быть. Фактической реализацией этой спецификации является cryptsetup и dm-crypt (модуль ядра Linux, он и делает операции шифрования на лету).

У LUKS есть две версии — v1 и v2. Все современные Linux-дистрибутивы используют вторую версию. Статья будет рассматривать именно вторую версию как более современную.

При создании зашифрованного раздела (luksFormat) процесс несколько отличается от VeraCrypt. Как минимум нас не заставляют крутить мышкой). Утилита cryptsetup обращается к системному генератору случайных чисел ядра Linux — /dev/urandom. Генерируется случайная последовательность бит нужной длины, например для режима aes-xts-plain64 (AES XTS) с ключом 512 бит (помним, что для XTS нужно два ключа, да?) генерируется 64 случайных байта. Этот мастер-ключ и будет шифровать и расшифровывать сектор за сектором на вашем диске.

Если вы знакомы с ядром Linux, то вы знаете, что существует два генератора случайных чисел — /dev/random и /dev/urandom. Давно на форумах есть холивары насчёт «что безопаснее». TL;DR сейчас разницы нет, и то и то использует одинаковый CSPRNG под капотом.

Погружение в генерацию случайных чисел ядра Linux

В старых версиях ядра эти устройства работали по-разному:

  • /dev/random раньше считался «истинно случайным». Он собирал аппаратный шум (тайминги прерываний диска, нажатия клавиш, сетевые пакеты) в пул энтропии. Как только этот пул заканчивался, /dev/random блокировал выдачу, а вместе с ней и программу, которая ждала свои заветные 32 байта.

  • /dev/urandom использовал тот же пул энтропии, но если он истощался, устройство не останавливало работу. Оно переключалось на генерацию псевдослучайных чисел с помощью CSPRNG (cryptographically secure pseudo random number generator).

И параноики считали, что /dev/random безопаснее, потому что это «истинная случайность», но что тогда, что сейчас это неправда. При переходе на генерацию псевдослучайных чисел значение инициализации (seed) берётся из того, что уже успела накопить система. Если есть хотя бы 128 или 256 бит случайных данных, смешанных в пуле, то криптографический алгоритм превращает их в непрерывный поток псевдослучайных чисел. Подобрать такое математически нереализуемо (2¹²⁸ или 2²⁵⁶ вариантов).

А как оно реализовано сейчас? С ядра Linux 5.6 подсистема CSPRNG была полностью переписана. Теперь оба устройства используют один и тот же движок на базе алгоритма ChaCha20. Теперь нет разницы между /dev/random и /dev/urandom, когда CSPRNG инициализирован.

Даже в первую микросекунду загрузки /dev/urandom является безопасным, потому что современные загрузчики, такие как systemd-boot, записывают при выключении устройства файл со случайным seed, чтобы при следующем запуске устройства CSPRNG сразу был проинициализирован.

Проблема недостатка пула энтропии была актуальна для серверов и виртуальных машин на Linux, потому что там недостаточно источников энтропии помимо RDSEED процессора. Ядро запущено в изолированной среде от внешнего и случайного мира, но все равно всеми силами собирает и сохраняет эту энтропию. Для надежного решения этой проблемы существует virtio-rng, но это совсем другая история.

Главное запомнить, что сейчас на загруженной системе нет разницы, что использовать: /dev/random или /dev/urandom. Не слушайте всяких балбесов в интернете.

Ключевые слоты, Argon2id и AFSplitter

Затем при добавлении пароля разблокировки (cryptsetup luksAddKey) cryptsetup измеряет производительность вашего процессора для KDF. Это нужно, чтобы подобрать такие параметры, чтобы расшифровка занимала ~2 секунды. Это нужно, чтобы одновременно было трудно подобрать пароль И разблокировка диска не занимала слишком много времени на слабом железе. По умолчанию cryptsetup использует уже известный вам argon2id.

Пароль и сгенерированная соль передаются в argon2id, мы получаем ключ шифрования слота. Этим ключом слота шифруется мастер-ключ. Но мастер-ключ не абы какой, а преобразованный с помощью механизма AFSplitter (Anti-Forensic splitter).

Мастер-ключ сначала «раздувается» в огромный массив данных, и только потом этот получившийся многокилобайтный массив зашифровывается с помощью ключа, созданного из вашего пароля.

Как работает AFSplitter/AFMerge?

Сначала определимся с тем, что такое полосы (stripe/blocks) для разделения секрета. 1 полоса — набор случайных байт длиной в размер мастер-ключа. В нынешнем cryptsetup фиксировано N = 4000, первые 3999 полос — случайные, а последняя вычисляется.

Для первых N-1 полос генерируются независимые случайные последовательности из того же CSPRNG.

Для запуска цепочки мы берем первую полосу. Затем считается A = SHA256(00 00 00 00 || содержимое первой полосы). Затем делается B = SHA256(00 00 00 00 || (A XOR содержимое второй полосы)). Затем делается C = SHA256(00 00 00 00 || (B XOR содержимое третьей полосы)) и т.д. Так мы прогоняем все 3999 полос через цепочку хешей и получаем финальный хеш. А для последней (4000-й) полосы мы записываем результат: мастер-ключ XOR финальный_хеш. Нули в начале не просто так, для 64-байтового ключа на каждом шаге считаются два хеша: SHA256(00 00 00 00 || x[0:32]) || SHA256(00 00 00 01 || x[32:64]).

Теперь мы получили огромный массив, в дальнейшем он будет зашифрован. Как нам потом извлечь мастер-ключ? Вспомним, что если A XOR B = C, то C XOR B = A.

При расшифровке cryptsetup прочитает все эти полосы. Но так как хеш-функция SHA-256 необратима и «раскрутить» её назад невозможно, сборка идет в ту же самую прямую сторону: cryptsetup берёт первые 3999 полос, шаг за шагом считает ту же самую цепочку (A, B, C…) и в итоге получает в точности тот самый финальный хеш. Затем делается финальный шаг: содержимое 4000-й полосы XOR финальный_хеш.

Так как в 4000-й полосе лежало мастер-ключ XOR финальный_хеш, финальный хеш взаимно уничтожается (XOR самого с собой дает 0), и мы получаем чистый мастер-ключ.

Если изменить бит в первых 3999 полосах, ключ с высокой вероятностью изменится полностью, а если изменить бит в последней полосе, изменится соответствующий бит ключа. В обоих случаях digest не совпадёт и LUKS не разблокируется. При потере всего одной полосы (ключ 32 байта) это уже 2²⁵⁶ вариантов.

Зачем нужен AFSplitter? На это есть несколько причин:

  • Гарантированное уничтожение слота при удалении. Современные SSD могут использовать wear levelling и не перезаписывать данные поверх старых ячеек памяти, они просто перенесут их на новое место, оставляя хвосты, которые сможет извлечь грамотный форензик. Из-за того, что массив AFSplit размазан по множеству секторов, с большей вероятностью один из таких хвостов, если и будет, то будет перезаписан, а значит — мастер-ключ не восстановить.

  • «Всё или ничего» (All-or-Nothing Transform). Если каким-то образом с помощью лабораторного оборудования удастся восстановить 99% данных, но не выйдет прочитать хотя бы 1 бит, то мастер-ключ будет совершенно иным.

  • Дополнительная микрозащита от брутфорса. Так как ключ расширяется до 128–256 КБ — это истощает пропускную способность памяти GPU или ASIC помимо использования тяжёлого argon2id.

Огромный массив AFSplitter шифруется тем же самым AES XTS. Теперь остаётся только записать все необходимые данные в LUKS-заголовок (начало диска) в виде JSON-строки: KDF и параметры (для argon2 — time cost, memory cost, parallelism и соль), длину ключа, алгоритм шифрования, количество AF-полос и какой алгоритм хеширования используется и точное местоположение (через offset), где находится этот зашифрованный AFSplitted мастер-ключ.

cryptsetup luksDump информация о слоте

Проверка ключа и разблокировка LUKS

Как потом понять, что мы получили правильный мастер-ключ? Для этого в LUKS-заголовке есть специальный digest — многократный hmac-sha256 от мастер-ключа.

При последующей загрузке после запроса пароля cryptsetup парсит JSON-заголовок, вычисляет, какой KDF и какие у него параметры, считает ключ слота, расшифровывает слот, проводит AFMerge и получает мастер-ключ. Этот мастер-ключ хешируется много-много раз и сверяется с digest, находящимся в заголовке. Если он сходится, то диск расшифрован успешно. Мастер-ключ передаётся dm-crypt в изолированный kernel keyring. Из userspace даже с root-правами его уже без дампа памяти не достать.


Ограничения шифрования и cold boot

Итак, вы молодец. Вы бесконечно круто зашифровали свой диск, но оставили скачиваться фильм с торрента и пошли гулять. Или снова сценарий, который мы уже рассматривали — у вас украли ноутбук, который был в режиме сна (как часто вы их выключаете?). Злоумышленник имеет физический доступ к устройству. Если он настоящий профессионал и вам не повезло, что планки памяти у вас легко извлекаются, то он может провести Cold Boot-атаку.

Cold-Boot атака

Cold Boot-атака — это способ взлома, при котором секреты извлекаются прямо из оперативной памяти, эксплуатируя остаточное сохранение данных.

Мы помним, что в оперативной памяти все хранится в виде электрического заряда. Что же может сделать злоумышленник, чтобы этот заряд как можно дольше оставался в оперативной памяти? Он может использовать жидкий азот, чтобы заморозить плашку. При очень низкой температуре данные могут сохраняться без питания от нескольких минут до нескольких часов, что позволяет вставить плашку в волшебный анализатор и сделать полноценный дамп. Затем в этом дампе можно попробовать найти мастер-ключ диска и таким образом его расшифровать, минуя подбор пароля.

У cold boot также есть вариация с перезагрузкой, когда питание экстренно сбрасывается и при следующем включении при загрузке с флешки уже извлекаются все данные. Но от подобной атаки есть попытка реализации защиты под названием TCG Platform Reset Attack Mitigation. Она обязывает UEFI-прошивку полностью очищать оперативную память, если система была перезагружена нештатно. За это отвечает специальный флаг — MOR bit (Memory Overwrite Request). Тем не менее атака все ещё возможна и зависит это от реализации UEFI, например, производитель может оставить проверку этого флага в незащищенной переменной в NVRAM материнской платы, которую легко подделать.

Но самым надежным способом защиты является шифрование памяти. Современные процессоры поддерживают технологии для прозрачного шифрования оперативной памяти на лету. На AMD есть SME и TSME (Transparent System Memory Encryption) — процессор просто шифрует с помощью aes всю оперативку перед отправкой в оперативную память с небольшими накладными расходами (до 2%), полностью прозрачно для операционной системы. Отличие SME от TSME — при SME ядро само решает, какие страницы памяти шифровать, а при TSME ядро даже не знает, что все зашифровано. У Intel всё то же самое, но называется чуть по-другому — TME (Total Memory Encryption).


Что учитывать на практике

Чему мы научились, Палмер? Пора закрыть свой 400-страничный отчёт по YKeyScore, шпиён.

  1. Определяйте модель угроз. Нужно ли вам шифровать диск и терять под 20% скорости диска или можно обойтись ситуативным контейнером?

  2. FBE надежно, но это не панацея. Метаданные все равно могут предательски утечь на незашифрованный диск, важно это помнить.

  3. Зашифрованные контейнеры VeraCrypt — отличное решение для безопасной и повседневной работы + для хранения и передачи по небезопасным каналам. Но все ещё не исключаем ириски утечки метаданных.

  4. Полнодисковое шифрование (FDE) мастхев при работе с особо чувствительными данными.

  5. Чем проще пароль, тем сложнее надо использовать параметры KDF.

  6. Теперь вы понимаете, как и почему программы для шифрования работают так, как работают. Кто знает, может, в дальнейшем придется писать собственные программы для шифрования.

  7. Выключайте устройство, когда не используете. BFU-режим (Before First Unlock) очень трудно пробить, и эта статья рассказывает об этом.

Шифруйте диски правильно, следите за opsec (простите) и не создавайте свой картель, как Пол Ле Ру, ведь против терморектального криптоанализа бессилен даже LUKS2.

Если вы нашли опечатку или ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter

Также по теме:

CVSS 3.1: восемь базовых метрик и шкала критичности

/База знаний

CVSS 3.1: как оценить критичность уязвимости

Как оценить уязвимость по CVSS 3.1 для bug bounty: восемь базовых метрик, примеры расчёта и типичные ошибки при составлении отчёта.
Прочитать

216

Пикси исследует скрытые данные в младших битах изображения

/База знаний

LSB-стеганография: что это и как скрывают данные в изображениях

Разбираемся, как устроены RGB и младшие биты пикселей, прячем текст в PNG на Python и извлекаем его обратно. Примеры кода и инструменты для анализа LSB.
Прочитать

116