AES Key Wrap в контексте JOSE применяется как механизм защиты ключа содержимого (Content Encryption Key, CEK) при формировании JWE. Он решает задачу безопасной передачи симметричного ключа, который используется для шифрования данных, без необходимости использовать асимметричное шифрование или передавать ключ в открытом виде.
AES Key Wrap основан на алгоритмах, определённых в RFC 3394 и расширении RFC 5649. В спецификации JOSE он представлен тремя вариантами:
Каждый из этих алгоритмов отличается только длиной ключа шифрования (KEK — Key Encryption Key), который используется для упаковки CEK.
В структуре JWE (JSON Web Encryption) всегда присутствуют два уровня ключей:
AES Key Wrap выполняет функцию обёртки CEK:
encrypted_keyБиблиотека jose реализует AES Key Wrap как часть JWE алгоритмов
шифрования ключей. При использовании high-level API разработчик обычно
не вызывает алгоритм напрямую — он выбирается через поле
alg в заголовке JWE.
Пример использования A128KW:
import { generateSecret, CompactEncrypt } from 'jose'
// ключ шифрования контента (CEK будет сгенерирован автоматически)
const plaintext = new TextEncoder().encode('секретные данные')
// симметричный ключ для wrapping (KEK)
const kek = await generateSecret('A128KW')
const jwe = await new CompactEncrypt(plaintext)
.setProtectedHeader({
alg: 'A128KW',
enc: 'A256GCM'
})
.encrypt(kek)
console.log(jwe)
В этом примере:
alg: 'A128KW' определяет способ упаковки CEKenc: 'A256GCM' определяет алгоритм шифрования
данныхkek используется для защиты ключа CEKИспользует 128-битный ключ AES. Это наиболее распространённый вариант благодаря балансу между безопасностью и производительностью.
Использует 192-битный ключ AES. Менее распространён, но повышает криптостойкость по сравнению с 128-битным вариантом.
Использует 256-битный ключ AES. Максимальный уровень стойкости среди трёх вариантов.
AES Key Wrap не является режимом шифрования данных в классическом смысле (как CBC или GCM). Он предназначен исключительно для защиты ключей.
Основные особенности:
Внутренне алгоритм выполняет несколько раундов AES-шифрования над блоками ключа CEK, перемешивая их с контрольными значениями.
При формировании JWE структура заголовка обычно выглядит так:
{
"alg": "A256KW",
"enc": "A256GCM"
}
Где:
alg — алгоритм защиты CEK (AES Key Wrap)enc — алгоритм шифрования содержимогоВ зависимости от выбранного alg библиотека jose
автоматически применяет соответствующий Key Wrap.
В библиотеке jose KEK может быть:
CryptoKey через Web Crypto
API)generateSecretimportKeyПример импорта ключа:
import { importJWK, CompactEncrypt } from 'jose'
const jwk = {
kty: 'oct',
k: 'GawgguFyGrWKav7AX4VKUg',
alg: 'A128KW'
}
const key = await importJWK(jwk, 'A128KW')
const jwe = await new CompactEncrypt(
new TextEncoder().encode('данные')
)
.setProtectedHeader({ alg: 'A128KW', enc: 'A128GCM' })
.encrypt(key)
AES Key Wrap алгоритмы в JOSE имеют строгие требования:
Несоответствие длины ключа приводит к ошибке на этапе шифрования или импорта.
AES Key Wrap используется в следующих сценариях:
Особенно важен он в системах, где требуется:
В реализации jose типичны следующие проблемы:
alg и фактического типа ключаБиблиотека строго валидирует параметры на этапе выполнения, поэтому ошибки проявляются сразу при создании JWE.