Во многих местах не соблюдаются законы о конфиденциальности, в определённых ситуациях вас могут заставить расшифровать медиафайлы, или, что ещё хуже, могут обвинить в нарушении. Скрытый том Veracrypt полезен в первом случае, но не во втором.
Именно поэтому я создал Phantomdrive.
Phantomdrive — это полностью опенсорсный USB-накопитель, который при первом подключении отображается как 8-гигабайтный диск. Операционная система никак не может обнаружить остальную часть диска. Если пользователь редактирует текстовый файл на диске, используя в качестве содержимого password: PUTYOURPASSWORDHERE, накопитель отключается и повторно подключает второй скрытый раздел, а AES-256 шифрует/расшифровывает данные на месте.
С Phantomdrive вы, надеюсь, сможете обойти авторитарных представителей правительства, коррумпированную полицию и всех, кто не уважает основные права на шифрование.
Дизайн
Все компоненты с открытым исходным кодом: прошивка, аппаратное обеспечение и механическая разработка. Инструменты, которые я использовал для разработки устройства, также являются опенсорсными. Давайте перейдём к проектированию!
Для этого проекта я использовал интересный маленький чип под названием CH569. Он от той же компании, которая производит чип USB-to-Serial (CH340), используемый практически во всех поддельных платах Arduino.
Я использую USB3, SD/eMMC и блок AES. Блок шифрования SM4, который вы видите выше, по-видимому, стандартизирован для коммерческой криптографии в Китае (так говорит «Википедия»).
Из-за растущего спроса на ИИ стоимость памяти eMMC необычайно высока, поэтому я выбрал SD-карту в качестве памяти. Кто-то найдёт вашу SD-карту, если разберёт устройство, но, конечно, всё будет зашифровано. Я использовал эпоксидную смолу для склеивания корпуса, а это значит, что злоумышленнику придётся уничтожить его, чтобы проникнуть внутрь. Если это не соответствует вашим требованиям, я предлагаю поискать что-то другое 😊
Как только цены на eMMC снизятся, появится версия, использующая её.
Устройство простое: микросхема CH569, USB-порт, два понижающих преобразователя, кнопка обновления прошивки, SD-карта и некоторые вспомогательные компоненты. Также есть точки тестирования UART, которые помогают в разработке прошивки.
Криптография
Я не получал уведомлений, когда «люди» открывали для себя несколько сгенерированных ИИ проблем на GitHub в моём репозитории. Они описывали смесь уже исправленных проблем, галлюцинаций ИИ и мелких багов, раздутых до невероятных размеров. Reddit довольно быстро набросился на тему, пока я спал.
Это была большая ошибка с моей стороны, я должен был хотя бы заметить, что люди реагируют. Большинство из багов были несущественными, за исключением AES-XTS, о котором я расскажу ниже.
Что касается безопасности устройства, я проверил её с помощью функциональных тестов, подобных этому, и вы можете быть уверены, что шифрование работает, а также пропустил его через реализацию AES в OpenSSL.
Функция вывода ключа (ФВК)
ФВК, или «Функция вывода ключа», — это функция, используемая для генерации ключа в криптографии. Давайте начнем с худшего способа получения ключа AES.
Мы берём наш пароль, добавляя к нему нули, пока он не станет 32 байтами (для AES-256), и это наш ключ. С плохим паролем, например, «password1234», мы можем взломать его методом перебора за считанные минуты. С хорошим паролем это займёт часы, а с действительно хорошим — от лет до десятилетий.
Но что, если злоумышленник использует предварительно вычисленную таблицу ключей? Это означает, что ему даже не нужно ничего подбирать. Для решения этой проблемы мы добавляем соль.
Если каждое устройство имеет уникальную соль, злоумышленнику необходимо вычислять ключи для него по отдельности, поэтому проблема с таблицей поиска исчезает. Поскольку соли разные, вы не можете вынуть SD-карту из одного устройства и вставить её в другое. Вот как получить свою соль…
udevadm info --query=property --name=/dev/sdc | grep ID_SERIAL_SHORT ID_SERIAL_SHORT=Phantomdrive:34FC1FA7145467F7
Итак, 34FC1FA7145467F7 — это соль этого устройства, которая вам понадобится для восстановления данных, если оно когда-либо выйдет из строя. К сведению: вы можете изменить «Phantomdrive» и PID/VID USB на что угодно, обновив прошивку для повышения скрытности.
Теперь предположим, что у нашего злоумышленника есть очень мощный компьютер, он получил вашу соль и теперь будет вычислять свою собственную «таблицу». Чтобы немного усложнить задачу, мы добавим 100 000 раундов SHA-256 к KDF.
Я выбрал 100 000 раундов, потому что разблокировка устройства занимает около 3 секунд, а, если выбрать больше, то это займёт больше времени. Я не могу использовать такие алгоритмы, как Argon2, потому что они требуют больших объёмов памяти. Если у вас есть лучший способ реализовать это, не увеличивая время разблокировки более чем на 5 секунд, я был бы рад с ним познакомиться, но сейчас мы достигли предела вычислительных возможностей этого устройства.
Если вам нужна более высокая безопасность, то можно увеличить количество раундов KDF SHA256, поискать другое устройство или выполнить двойное шифрование искомого с помощью программного решения. Также можно просто отключить шифрование и использовать только программное шифрование.
Режимы AES
AES — это блочный шифр, то есть он может шифровать и расшифровывать фиксированный (16-байтовый) объём данных. Существуют различные режимы AES, позволяющие превратить его в потоковый шифр.
AES-ECB
AES-ECB, или электронная кодовая книга, — это наивный способ создания потокового шифра. Вы просто берёте каждый 16-байтовый блок открытого текста в вашем потоке и шифруете его. Вот и всё! Мы только что создали потоковый шифр. Однако это небезопасно по нескольким причинам.
Один и тот же блок открытого текста будет генерировать одинаковые блоки зашифрованного текста, что создаёт недостаток диффузии.
Злоумышленники могут удалять данные из зашифрованного текста, и при расшифровке открытый текст будет изменяться предсказуемым образом.
Поэтому это не лучший способ.
AES-CTR
AES-CTR или Counter — это способ решения вышеуказанных проблем. Он работает простым способом: вы шифруете свой счётчик с помощью AES, а затем выполняете операцию XOR над выходными данными и открытым текстом.
uint64_t i = 0; while(i < len(ciphertext)) { ctr = aes_encrypt(i); ciphertext[i] = plaintext[i] ^ ctr i++; }
Это псевдокод, но вы поняли суть.
Существует риск безопасности, связанный с «повторным использованием», о котором следует помнить при внедрении этого режима.
Злоумышленник восстанавливает ваш зашифрованный текст, возвращает устройство на место.
Вы записываете множество новых данных.
Злоумышленник снова восстанавливает ваш зашифрованный текст.
Если он сможет угадать один из зашифрованных текстов, то сможет восстановить и другой.
С этим устройством я получаю около 9 МБ/с на запись и 20 МБ/с на чтение с AES-CTR и 6 МБ/с на запись и 10 МБ/с на чтение с AES-XTS. Для меня это недостаточно большой прирост безопасности по сравнению со скоростью, чтобы оправдать переход на AES-XTS, но у вас может быть совершенно другая ситуация.
AES-XTS
AES-XTS, или режим модифицированной кодовой книги, — это стандарт шифрования дисков. Он работает с использованием двух ключей:
К1 — это ваш ключ данных, и
К2 — генерирует модифицированный ключ.
Для каждого сектора диска необходимо вычислить ключ настройки, исходя из номера сектора S.
Каждый 16-байтовый блок подвергается своей корректировке, в результате чего получаются T0, T1, T2... Tn. Затем вы шифруете блок за блоком свой открытый текст P, чтобы получить окончательный зашифрованный текст C.
Это решает проблемы повторного использования счётчиков, перечисленные выше, но работает немного медленнее.
Прошивка
Я использовал два проекта; спасибо их разработчикам.
Библиотека для микросхемы (BSP) https://github.com/hydrausb3/wch-ch56x-lib
Библиотека программирования ISP https://github.com/hydrausb3/wch-ch56x-isp
В прошивке есть несколько элементов, которые могут вас заинтересовать…
Перехват паролей
Устройство на самом деле не знает файловую систему, оно просто принимает команды USB WRITE10/READ10 и преобразует их в команды CMDx для SD-карты. Таким образом, для разблокировки мы просто смотрим на необработанные данные, в разблокированном состоянии это выглядит так:
void phantomdrive_snoop_write(uint8_t *buf, uint32_t len) { const char *prefix = "password:"; const size_t prefix_len = 9; uint32_t i; for (i = 0; i + prefix_len <= len; i++) { if (buf[i] != 'p') continue; if (memcmp(buf + i, prefix, prefix_len) != 0) continue; size_t pw_start = i + prefix_len; size_t pw_end = pw_start; while (pw_end < len && (pw_end - pw_start) < sizeof(pending_pw) && buf[pw_end] != '\n' && buf[pw_end] != '\r' && buf[pw_end] != '\0') pw_end++; size_t pw_len = pw_end - pw_start; // Copy the password into RAM here memcpy(pending_pw, buf + pw_start, pw_len); pending_pw_len = pw_len; // We then zero out this buffer so the // password is never written to the disk memset(buf + i, 0, pw_end - i); return; } }
Устройство не знает файловой системы, поэтому при блокировке оно вызывает эту функцию перед каждой записью. Оно отслеживает все записи и сопоставляет их с password:. Это означает, что если вы используете небезопасную часть диска для множества данных, вы можете получить случайное совпадение, если ваши данные содержат строку password:. Опять же, если это не соответствует вашим требованиям, вы можете изменить метод или поискать другое устройство.
Конец
Спасибо за чтение и поддержку этого начинания. Было интересно работать над ним, и он вызвал большой интерес в сообществе. Именно такое взаимодействие мотивирует меня продолжать работать над подобными проектами.
Если вы заинтересованы в поддержке, у нас уже открыта страница предварительного заказа!
