flattenedDecrypt используется для расшифровки JWE (JSON Web Encryption) в так называемом flattened-формате, который представляет собой компактную структуру с одним получателем и минимальной вложенностью. В библиотеке jose этот метод относится к низкоуровневым операциям работы с зашифрованными JWT и позволяет вручную управлять процессом дешифрования.
Flattened JWE отличается от общего JWE JSON Serialization тем, что вместо массива получателей используется одиночный объект. Это упрощает структуру и уменьшает накладные расходы при передаче данных.
Типичная структура выглядит следующим образом:
Именно эту структуру ожидает flattenedDecrypt.
Процесс расшифровки можно разложить на несколько этапов:
В библиотеке jose эти шаги инкапсулированы внутри flattenedDecrypt.
Метод имеет следующую структуру вызова:
import { flattenedDecrypt } from 'jose'
const { plaintext, protectedHeader, additionalAuthenticatedData } =
await flattenedDecrypt(jwe, key)
Рассмотрим базовый сценарий расшифровки симметрично зашифрованного JWE:
import { flattenedDecrypt } from 'jose'
const jwe = {
protected: 'eyJlbmMiOiJBMjU2R0NNIn0',
iv: '48V1_ALb6US04U3b',
ciphertext: '5eym8TW_c8Su...',
tag: 'XFBoMYUZodetZdvTiFvSkQ',
}
const key = new TextEncoder().encode('supersecretsharedkey123')
const { plaintext } = await flattenedDecrypt(jwe, key)
console.log(new TextDecoder().decode(plaintext))
В этом примере используется симметричное шифрование, где один и тот же ключ применяется для шифрования и расшифровки.
После декодирования protected заголовка он становится доступен в виде объекта:
const { protectedHeader } = await flattenedDecrypt(jwe, key)
console.log(protectedHeader.alg)
console.log(protectedHeader.enc)
Ключевые поля:
Эти значения критически важны для корректной интерпретации структуры JWE.
При использовании RSA или ECDH ключ передаётся в виде приватного ключа:
import { flattenedDecrypt } from 'jose'
import { importPKCS8 } from 'jose/key/import'
const privateKey = await importPKCS8(pem, 'RSA-OAEP-256')
const { plaintext } = await flattenedDecrypt(jwe, privateKey)
В этом случае процесс включает дополнительный этап:
Некоторые JWE могут содержать дополнительную аутентифицированную информацию (AAD), которая участвует в проверке целостности:
const { additionalAuthenticatedData } = await flattenedDecrypt(jwe, key)
AAD не расшифровывается, но влияет на проверку authentication tag. Если данные были изменены, проверка целостности завершится ошибкой.
На практике чаще всего встречаются следующие ошибки:
Если ключ не соответствует алгоритму alg:
Причина: неверный тип ключа или неправильный формат JWK.
Возникает при изменении ciphertext или tag:
Это означает нарушение целостности данных.
Если библиотека не поддерживает указанный enc, например устаревший или нестандартный:
В jose существует также метод decrypt, который работает с полным JWE JSON Serialization (с массивом recipients).
Разница:
Flattened вариант используется чаще в API и микросервисах, где нет необходимости в мультиадресной доставке.
На уровне реализации flattenedDecrypt выполняет:
При работе с flattenedDecrypt важно учитывать:
Библиотека jose использует Web Crypto API, поэтому flattenedDecrypt работает:
При этом поведение полностью унифицировано, что позволяет использовать один и тот же код в разных средах.
flattenedDecrypt применяется в случаях:
Особенно часто используется в связке с compact encryption pipeline, где требуется минимальный размер и простая структура сообщения.