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

В случае с секретами для приложений всё не так просто. Вы никогда не знаете, где работает ваше приложение, насколько надёжна среда исполнения и может ли кто-то перехватить или подменить данные приложения снаружи. В этом случае решение видится одно — стараться хранить секрет в памяти минимально возможное время. Получил секрет, использовал по назначению и удалил из памяти. Таким образом мы снижаем вероятность, что он окажется где-то в core.dump, трейсе упавшего приложения или снапшоте виртуальной машины. 

Подробнее я затрагивал вопросы по дампу ОЗУ на вебинаре «Слёрм» о том, как прятать секреты приложения и в докладе про безопасную доставку секретов на Deckhouse Conf 2025. Но в этих выступлениях не было решения, о котором я расскажу в статье. 

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

Секреты под прицелом

Простые системы хранения секретов (далее — СХС) либо совсем не шифруют данные, либо могут хранить ключ для шифрования в каком-то файле на диске. Более продвинутые не хранят ключ в персистивном хранилище: он находится только в памяти процесса. И тут остро встает вопрос «доверенной среды исполнения». 

Если ваша СХС работает на «железном» сервере, то извлечь что-то из его памяти, не внося изменений в аппаратную конфигурацию, довольно проблематично. А тем более сделать это незаметно, не выключая машину.

Другое дело, если СХС работает на хосте, запущенном в среде виртуализации. Со стороны виртуализации можно сделать снапшот памяти виртуальной машины и диска, причём незаметно для самой ВМ. Более того, во многих компаниях такие снимки регулярно делаются для резервного копирования либо выполняются при миграции виртуальных машин с одного гипервизора на другой. И со стороны может быть довольно сложно определить — происходит легитимная операция или же у вас пытаются украсть виртуалку с секретами.

Дополнительных проблем добавляет то, что для администраторов виртуализации все виртуальные машины, в общем-то, одинаковые. Когда у вас тысячи ВМ, в которых крутится непонятно какой приклад (а для администраторов это, по сути, и не важно, так как доступа к прикладу они не имеют), легко не уследить за тем, что какие-то из этих виртуальных машин нельзя снапшотить. Более того, не все средства виртуализации поддерживают «запрет на снапшотинг».

Более или менее надёжно эту проблему решает программно-аппаратный комплекс, или ПАК, когда СХС запускается на каких-то «железных» серверах, вмешиваться в работу которых снаружи нельзя. Но и тут есть минусы. Стоимость ПАК может быть сильно выше стоимости ПО. Обновлять и обслуживать ПАК трудозатратнее и дороже. Обеспечивать его бесперебойную работу — тоже. Как и проводить какие-то миграции, переезд инфраструктуры. Я думаю, все согласятся, что в этом плане виртуализация даёт огромные преимущества по сравнению с ПАК.

Как проблему решают производители ПО

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

Вот выдержки из требований к среде эксплуатации одного из средств криптографической защиты информации, существующего на российском рынке:

Исключить возможность попадания в ОС хостовой машины, а также в гостевую ОС программ, позволяющих, пользуясь ошибками ОС, повышать предоставленные привилегии.

На ПЭВМ и в виртуальной среде не должны устанавливаться средства разработки ПО и отладчики. Если средства отладки приложений нужны для технологических потребностей организации, то их использование должно быть санкционировано администратором безопасности. При этом должны быть реализованы меры, исключающие возможность использования этих средств для редактирования кода и памяти СКЗИ и приложений, использующих СКЗИ, а также для просмотра кода и памяти СКЗИ и приложений, использующих СКЗИ, в процессе обработки СКЗИ защищаемой информации и/или при загруженной ключевой информации.

Или даже такое:

На снапшот ВМ, сделанный после ввода ключевой информации, должны распространяться требования по обращению с ключевыми носителями.

То есть запрет на снапшотинг памяти или отладку ПО реализуется не столько или не только за счёт самого ПО, сколько административными мерами защиты.

Но что, если мы полны паранойи и не то чтобы не доверяем административным методам, а всё-таки хотим добавить технологических ограничений? Что можно предпринять в таком случае?

Как HashiСorp Vault шифрует данные

Давайте рассмотрим на примере HashiСorp Vault, как происходит шифрование:

Клиент — приложение или пользователь — подключается к Vault и отправляет запрос на чтение данных. Эти операции шифруются TLS (зелёный цвет на схеме). Если операция чтения провалидирована на router, то происходит чтение из зашифрованного с помощью AES хранилища Storage (оранжевый цвет). Данные расшифровываются с помощью ключа key, хранящегося в памяти процесса. В этот момент расшифрованный блок данных присутствует в памяти Vault в открытом виде — вплоть до передачи клиенту.

Если сделать снимок ВМ в этот момент, можно получить доступ к этому конкретному секрету. Но основная проблема в том, что также можно получить и доступ к ключу key. А имея доступ к зашифрованному Storage или снапшоту Vault, можно расшифровать его целиком. То есть получить доступ не только к секрету, который был прочитан в какой-то конкретный момент времени, а вообще ко всем секретам в системе. И — что самое неприятное — со стороны хранилища секретов не будет никаких аудит-логов про то, что такой доступ был получен, ведь извлечение данных может происходить без участия СХС.

Действительно ли проблема существует?

Vault шифрует свои данные с помощью AES256-GCM96. То есть это не только шифрование, но и аутентификация зашифрованных данных, AEAD (Authenticated Encryption with Associated Data). С одной стороны, это даёт возможность при расшифровке проверить, что данные были зашифрованы именно этим ключом, а не просто какой-то мусор подложили. А с другой… позволяет проверить, что данные были зашифрованы именно этим ключом!

То есть если снять дамп памяти, разбить его на части по 32 байта (256 бит) и пробовать расшифровывать заведомо существующую в Vault и расшифровываемую запись (например, core/master), то путём вполне конечного перебора можно найти те самые 32 байта, с помощью которых проверка AEAD пройдёт.

Внешнее шифрование

В такой непростой ситуации поможет дополнительное шифрование — seal wrap, которое мы реализовали в Deckhouse Stronghold EE.

Если мы будем дополнительно шифровать критичные данные с помощью ещё одного слоя шифрования через внешний криптоконтроллер, то утечка ключа key и хранилища Storage не приведёт к компрометации всех данных. Например, в случае с виртуализацией наличие снапшотов виртуальных машин не даст возможность незаметно от системы аудита расшифровать данные в хранилище.

На схеме синим цветом обозначены данные, зашифрованные одновременно и AES (с помощью ключа key), и неизвлекаемым ключом, находящимся внутри HSM. При этом на стороне HSM доступ к открытым данным не предоставляется, так как он работает с данными, зашифрованными AES-шифрованием. Даже если злоумышленник внедрится в канал связи с HSM, к открытым данным он доступ не получит.

В данной схеме — даже в случае утечки ключа key из памяти СХС — будет невозможно расшифровать данные из Storage. Максимум — это данные из cache, то есть те секреты, которые были явно прочитаны в процессе работы с хранилищем. Для ещё большей безопасности cache можно отключить. Это снижает производительность системы (каждый запрос на чтение явным образом читается из Storage и расшифровывается через HSM и AES), но снижает угрозу утечки секретов через снапшот памяти виртуальной машины.

На практике бывает так, что не для всех типов секретов нужна такая безопасная безопасность, поэтому часть секретов можно шифровать дополнительным шифрованием, а часть — не шифровать. Администратор СХС сам выбирает, какие типы секретов должны быть обёрнуты дополнительным слоем шифрования.

Перешифрование данных

Может возникнуть резонный вопрос, а что делать, если потребуется сменить HSM или ключ в нём? Ведь данные в хранилище зашифрованы старым ключом. Для этого при сохранении данных в Storage в метаинформации записываются данные о ключе, которыми были дополнительно зашифрованы данные. Таким образом можно определить, какой ключ использовать при расшифровании прочитанных с хранилища данных.

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

Для миграции на новый ключ в Stronghold дополнительно реализован метод rewrap. Он позволяет прочитать из хранилища все данные, зашифрованные «старым» ключом, перешифровать их «новым» ключом и сохранить в Storage. Это может быть полезно не только при смене HSM, но и при плановой ротации ключей шифрования.

Когда нет HSM

Мы много говорили про HSM в контексте двойного шифрования, и это действительно максимально надёжно. Производители HSM гарантируют, что ключ шифрования нельзя извлечь из устройства, не уничтожив в процессе сам ключ. Для этого HSM оснащены специальной защитой на аппаратном уровне. То есть использование двойного шифрования совместно с HSM действительно кратно увеличивает безопасность при хранении секретов.

Но что делать, если у нас нет HSM или же полностью облачная инфраструктура? Поможет ли как-то двойное шифрование, особенно в вариантах со снапшотом памяти ОС? Давайте разберёмся.

Помимо поддержки двойного шифрования через HSM-модули, Stronghold поддерживает двойное шифрование через другой Stronghold. Это так называемый механизм транзитного шифрования (transit). 

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

Поэтому даже при отсутствии HSM двойное шифрование может повысить безопасность ваших данных.

Приятные мелочи

При разработке Deckhouse Stronghold мы учитываем, что драйвером индустрии являлся (да и, наверное, является) HashiCorp Vault. Поэтому мы стараемся максимально поддерживать совместимость нашего продукта с HashiCorp Vault. 

Во-первых, с точки зрения API. Stronghold позволяет пользователю применять привычные инструменты и библиотеки, в том числе для работы с enterprise-функциями, например с такими, как autosnapshots (резервное копирование по расписанию) или namespaces. То есть ваши любимые библиотеки или Terraform-манифесты будут работать со Stronghold так, как если бы это был Vault Enterprise.

Во-вторых, мы стараемся поддерживать совместимость на уровне хранения данных. Если вы ранее пользовались Vault Enterprise, то сможете взять его бэкап или снапшот либо просто запустить Stonghold вместо Vault, и все ваши данные останутся на месте: пространства имён, секреты, права доступа, политики в пространствах имён и так далее. Например, OpenBao относится к совместимости более вольно: их реализация пространств имён несовместима с HashiСorp Vault, что усложняет возможную миграцию.

В случае с механизмом двойного шифрования мы придерживались такого же подхода. Вы можете взять данные от Vault Enterprise, которые были зашифрованы через HSM и Seal Wrap, запустить Stronghold — и все данные будут доступны в последнем. Для переезда не нужны никакие небезопасные «миграторы», вы просто запускаете новое приложение на старых данных.

Что даёт механизм двойного шифрования

Если говорить про Vault-совместимые хранилища секретов, то механизм двойного шифрования поддерживается в системах enterprise-уровня, таких как HashiCorp Vault Enterprise или Deckhouse Stronghold EE, и отсутствует в их младших версиях — HashiCorp Vault, Deckhouse Stronghold CE — и различных форках Vault, например в российских или OpenBao.

Что даёт пользователям двойное шифрование?

В первую очередь оно увеличивает безопасность хранения секретов, особенно для систем, развёрнутых на виртуальных машинах.

Российским пользователям оно позволяет легко внедрить сертифицированное шифрование ГОСТом хранимых данных. Если HSM поддерживает ГОСТ-шифрование, то данные в Storage будут зашифрованы ГОСТом. Это позволяет подстроиться под требование регуляторов.

А ещё двойное шифрование позволяет использовать HSM как «второй фактор» для работы СХС. 

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

P. S. 

Больше наших материалов по теме:

Комментарии (1)


  1. Litemanager_remoteadmin
    10.11.2025 08:22

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