[Документация Yandex Cloud](../../index.md) > [Yandex Key Management Service](../index.md) > [Концепции](index.md) > Симметричное шифрование > Симметричное шифрование

# Симметричное шифрование в KMS

Одна из доступных схем шифрования в KMS — _симметричное шифрование_. В этой схеме для шифрования и расшифрования используется один и тот же (симметричный) ключ. В KMS применяется несколько симметричных алгоритмов:
  * [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) с длиной ключа 128, 192 или 256 бит в режиме [GCM](https://en.wikipedia.org/wiki/Galois/Counter_Mode). 
  * [AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) с длиной ключа 256 бит в режиме [CBC](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_block_chaining_(CBC)) с имитозащитой [HMAC](https://en.wikipedia.org/wiki/HMAC).
  * [Кузнечик](https://ru.wikipedia.org/wiki/Кузнечик_(шифр)) по [ГОСТ Р 34.12-2015](https://protect.gost.ru/v.aspx?control=7&id=200990) с длиной ключа 256 бит и имитозащитой [OMAC](https://ru.wikipedia.org/wiki/CBC-MAC#OMAC).

Важное условие безопасного шифрования — это использование криптографически стойкого генератора псевдослучайных чисел (необходим для генерации ключей шифрования, векторов инициализации). В KMS используется собственная реализация алгоритма [Fortuna](https://en.wikipedia.org/wiki/Fortuna_(PRNG)), агрегирующая энтропию с различных источников (RDSEED и RDRAND, /dev/urandom, энтропия с хостов).

В случае использования [аппаратного модуля безопасности (HSM)](hsm.md) ключи шифрования генерируются внутри модуля HSM, используя встроенный в HSM надежный генератор энтропии.

Криптоматериал, содержащийся в версиях ключей, недоступен в открытом виде вне сервиса KMS. Шифрование и расшифрование в KMS выполняются с помощью криптографических операций [encrypt](../api-ref/SymmetricCrypto/encrypt.md) и [decrypt](../api-ref/SymmetricCrypto/decrypt.md).

## Операция Encrypt {#encryption}

1. Принимает на вход идентификатор ключа (`keyID`) вместе с открытым текстом (`plaintext`).
    
    Если нужно выполнить шифрование с использованием неосновной версии ключа, передайте на вход операции идентификатор произвольной активной версии ключа (`versionId`).
1. Шифрует открытый текст с использованием алгоритма и криптоматериала основной версии ключа. 
1. Возвращает полученный шифртекст (`ciphertext`).

Encrypt-операция подходит для шифрования данных небольшого размера. Максимальный размер `plaintext` — 32 КБ. Для шифрования данных большего объема используйте [envelope encryption](envelope.md).

## Операция Decrypt {#decryption}

1. Принимает на вход идентификатор ключа (`keyID`) и шифртекст (`ciphertext`).

    Шифртекст, сгенерированный encrypt-операцией, содержит идентификатор версии (`versionId`), использовавшейся при шифровании. Алгоритм и криптоматериал для расшифрования берутся именно из этой версии ключа.
1. Расшифровывает текст.
1. Возвращает в качестве результата открытый текст (`plaintext`). 

Операции encrypt и decrypt в KMS поддерживают передачу AAD-контекста (англ. Additional Authenticated Data) в качестве параметра (`aadContext`), что позволяет дополнительно обезопасить шифруемые данные.

## AAD-контекст {#add-context}

Additional Authenticated Data (AAD) – дополнительные данные, передаваемые на вход операций [encrypt](../api-ref/SymmetricCrypto/encrypt.md) и [decrypt](../api-ref/SymmetricCrypto/decrypt.md). Для успешного расшифрования необходимо передать такой же AAD-контекст, что был передан для шифрования. 

AAD-контекст тесно связан с шифруемыми данными (без знания AAD-контекста невозможно расшифровать шифртекст), но не повышает криптостойкость шифртекста и не является его частью. Задача AAD-контекста – защита от [confused deputy](https://en.wikipedia.org/wiki/Confused_deputy_problem) атак с помощью дополнительной проверки данных при расшифровании.

{% note info %}

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

{% endnote %}

#### Пример confused deputy атаки {#example}

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

* Алиса воспользовалась сервисом и указала свой адрес.
    * В базе данных появилась новая запись, помеченная как принадлежащая Алисе. Запись содержит адрес в зашифрованном виде. 
    * Алиса может видеть свой адрес: из базы данных будут выбраны, расшифрованы и показаны принадлежащие ей записи.
* Другой пользователь — Труди, получил доступ к базе данных. 
    * У Труди нет ключа шифрования и она не может расшифровать содержимое базы данных, но может модифицировать ее содержимое. 
    * Труди помечает запись с зашифрованным адресом Алисы, как принадлежащую ей и получает возможность увидеть адрес Алисы.

Проблема решается, если при шифровании в качестве AAD-контекста передавать, например, логин пользователя. В таком случае: 
1. Труди попытается посмотреть данные Алисы, помеченные им, как свои.
1. Сервис будет передавать в качестве AAD-контекста логин Труди вместо логина Алисы.
1. Расшифровать данные не получится.

## Примеры использования {#examples}

* [Шифрование данных с помощью CLI и API Yandex Cloud](../tutorials/encrypt/cli-api.md)
* [Шифрование данных с помощью SDK Yandex Cloud](../tutorials/encrypt/sdk.md)
* [Шифрование секретов в Yandex Managed Service for Kubernetes](../tutorials/kms-k8s.md)
* [Безопасная передача пароля в скрипт инициализации](../tutorials/secure-password-script/index.md)