Криптография за облаками
Все шутки об облачных провайдерах условно делятся на две категории: как мы переезжали в облако и как мы возвращались обратно в свой дата-центр. На самом деле не всё так печально. Даже самые консервативные специалисты начали понимать, что переезд в облако – это не просто запуск виртуальных машин где-то далеко, но и перемена многих подходов к тому, как должны быть устроены ИТ-инфраструктура и безопасность.
Облако – это не набор самостоятельных решений, собранных под одним брендом хитрыми маркетологами. Напротив, большинство сервисов интегрированы друг с другом, взаимно дополняют функционал и, можно сказать, приобретают таким образом дополнительную ценность. Сегодня мы посмотрим, как устроена криптография в облаке, которая может быть интегрирована практически в любое современное решение.
Amazon Web Services
Изучать криптографические сервисы мы будем на примере Amazon Web Services (AWS). Другие облачные провайдеры предлагают примерно то же самое, поэтому разобраться с другими терминами не составит особого труда.
Сервисов, реализующих криптографию, в AWS несколько:
- Инструмент управления сертификатами AWS Certificate Manager — аналог того, что вы развёртываете у себя в компании, чтобы выписывать сертификаты пользователям и серверам.
- Сервис управления секретами AWS Secrets Manager – сервис, предназначенный для хранения и извлечения различных данных для доступа к базам данных, API-ключам и т. п. Спросите у ваших DevOps, они расскажут подробнее.
- AWS Cloud HSM – облачный аппаратный модуль безопасности, с помощью которого можно генерировать и использовать в облаке AWS собственные ключи шифрования. Такой же, как у вас в серверной, только где-то в ЦОДе за океаном.
- AWS Key Management Service – служба, предназначенная для создания криптографических ключей, которые потом можно использовать в приложениях или сервисах AWS.
Про последний сервис AWS Key Management Service (или просто KMS) мы поговорим подробнее.
AWS Key Management Service
KMS – это региональный сервис, а это значит, что в каждом регионе AWS он уникален и, например, ключи из региона eu-central-1 нельзя использовать в us-east-1. Кроме этого, KMS – ещё и публичный, следовательно, получить доступ к нему можно из любой точки мира, не ограничиваясь отдельными VPC.
Основные задачи сервиса – это создавать, хранить ключи и управлять ими, а также решать задачи собственно шифрования и расшифровывания данных. KMS без проблем работает как с симметричным, так и с ассиметричными ключами. Криптографические ключи, кстати, никогда не покидают пределы KMS, как того требует FIPS 140-2 второго уровня, но об этом позже.
Основой всех операций в KMS является Customer Master Key (CMK) – основной ключ, которым пользуется KMS для криптографических операций. CMK – это даже не ключ, а контейнер, который внутри себя содержит идентификатор ключа, дату создания, политику использования, состояние, ну и, собственно, саму ключевую информацию. Ключевая информация может быть как сгенерирована вами самостоятельно и загружена на сервер, так и создана прямо на сервере. При этом, если вы решили сделать ключ самостоятельно, то KMS предварительно зашифрует его, прежде чем сохранить на диске.
Типовые базовые операции показаны на схеме:
Как можно заметить, ключ CMK не покидает KMS и регион, а значит, вытащить его не получится. Взаимодействие происходит только через API, а нашему пользователю будет достаточно разрешений на использование ключа, чтобы воспользоваться сервисом. При этом настроить KMS можно причудливым образом, когда одним пользователям разрешено только шифровать данные, а другим только расшифровывать. Ситуации случаются разные.
При использовании CMK есть одно существенное ограничение – им можно зашифровать данные объёмом до 4 Кб. Зачем он тогда такой нужен в реальном мире? Это слишком серьёзное ограничение, не так ли? Не совсем.
Data Encryption Key
Есть ещё один тип ключей, доступный в KMS – это Data Encryption Key (DEK). И вот этот DEK уже не имеет ограничений в 4 Кб. Но и сценарий создания другой: KMS создает этот ключ, но не хранит у себя, потому что в этот раз KMS сам не занимается шифрованием, это делаете вы или сервис, которому это потребуется. Когда мы решаем создать DEK-ключ, то мы получаем две версии этого ключа:
- plaintext-версия, который можно использовать прямо сейчас;
- шифрованная версия того же ключа, зашифрованная ключом CMK, с помощью которого его создали.
Идея в том, что, получив ключ, а затем зашифровав данные, вы удаляете этот ключ навсегда. Итого у вас на руках остается зашифрованные данные и зашифрованный ключ.
В обратную сторону всё работает так же: вы отправляете зашифрованный ключ в KMS, получаете DEK и расшифровываете свои данные.
Давайте посмотрим совсем простой пример. Зашифруем небольшой файл с помощью KMS. Сначала отправимся в консоль KMS и создадим свой CMK:
Естественно создать можно как симметричный ключ, так и ключевую пару, но для простоты ограничимся симметричным. Кроме этого, здесь же можно выбрать источник ключевой информации. Далее дадим нашему ключу описание и название:
Далее нужно указать учётную запись, которая будет управлять ключом, и кто сможет производить с помощью него криптографические операции:
Далее мы увидим полученную политику в формате JSON и согласимся с результатом:
Готово. Теперь с помощью консоли AWS CLI мы:
- создадим файл supersecret.txt;
- зашифруем с помощью AWS KMS, указав alias нашего ключа, и получим supersecret.enc;
- убедимся, что файл действительно зашифрован;
- благополучно расшифруем наш supersecret.enc в decoded_supersecret.txt и получим исходный текст.
Всё довольно просто. А теперь посмотрим, как это интегрируется с другими службами AWS, например с S3.
А теперь шифрование!
Важно напомнить, что сами по себе хранилища не зашифрованы. Совсем. А вот объекты в них – очень даже. При этом, у нас есть несколько вариантов обеспечения шифрования наших бесценных файлов. Если отбросить утопический сценарий, когда пользователь самостоятельно будет шифровать свои файлы перед отправкой в хранилище, у нас остаются три варианта шифрования на стороне непосредственно сервера:
1. Server-side encryption with customer-provided keys (SSE-C) – шифрование на стороне сервера, в котором ключи предоставляет клиент. Это, конечно, безопасно в том смысле, что вы будете лично предоставлять ключ шифрования для своих файлов, но может стать крайне неудобным и ресурсозатратным, когда файлов станет слишком много.
2. Server-side encryption with Amazon S3-Managed keys (SSE-S3) – в этом случае AWS сам отвечает не только за шифрование, но и за ключи. S3 сгенерирует свой мастер-ключ и с помощью него будет шифровать все получаемые файлы. Это удобно и просто и даже является методом шифрования S3 по умолчанию. Но в данном сценарии вы теряете управление мастер-ключом, а значит, о каком-либо разделении полномочий между пользователями можно забыть.
3. Server-side encryption with customer master keys Stored in AWS Key Management Service (SSE-KMS) – это почти как предыдущий SSE-S3, но ключ будет взят из KMS, куда вы предварительно его и поместите. При этом, на базе CMK для каждого загружаемого файла будет сгенерирован свой DEK для шифрования каждого объекта. Вам даже необязательно использовать тот же дефолтный CMK, можно сделать отдельный ключ для S3. Если представить все варианты в виде таблицы, то получается так:
Давайте посмотрим, как это будет выглядеть на практике. Сначала создадим новое хранилище:
Теперь загрузим туда фотографию Марса из Википедии:
Не забываем указать, что шифровать мы хотим нашим CMK:
После успешной загрузки файла мы можем проверить, что он без проблем открывается, потому что у нашей учётной записи есть доступ к ключу. А теперь давайте заберём у нашей учётной записи доступ к службе KMS.
Делается это через сервис Identity and Access Management (IAM) с помощью несложного JSON:
Теперь при обращении к нашему файлу мы получим:
Таким образом, без доступа к ключам из KMS даже легитимный пользователь не может получить доступ к файлам, так как нет возможности их расшифровать.
Подобным образом другие службы AWS и даже сторонние приложения могут быть интегрированы с KMS, создавая единую инфраструктуру шифрования для всего предприятия.
Материал подготовил сотрудник компании «Газинформсервис» Сергей Полунин.
Блог Сергея можно почитать по ссылке.