JavaScript SubtleCrypto генерирует 176-битные ключи AES вместо 128-битных?

Я работаю над игрой, которая будет взаимодействовать с сервером NodeJS для различных целей, и в настоящее время я пытаюсь реализовать некоторое шифрование AES для полезных данных запроса. Все работало нормально во время тестирования между сервером и тестовым инструментом, сделанным на JS, но когда я попытался перенести клиентский код на другой язык, который не имеет реализации Web Crypto/Subtle Crypto, я начал получать ошибки о ключе AES. длина.

Изучив его, я обнаружил, что генерируемый ключ AES (через window.crypto.subtle.generateKey) имеет длину 176 бит, хотя я указал длину ключа AES 128. Я экспортирую ключ в формате JWK, и странно, что алгоритм указан как A128CBC, предполагая, что он должен быть 128-битным.

Поскольку я все равно буду генерировать новый ключ, я без колебаний опубликую здесь экспортированный JWK:

{
  "alg": "A128CBC",
  "ext": true,
  "k": "J3SQ0IjwlJnJwu0EadenLg",
  "key_ops": [
    "encrypt",
    "decrypt"
  ],
  "kty": "oct"
}

Кто-нибудь может объяснить, откуда берутся эти дополнительные 6 байт? Реализация AES на портированной стороне клиента требует 128-битных ключей и просто выдает ошибки, если это не 128, что приводит к остановке всего проекта до тех пор, пока это не будет решено.


person IceMetalPunk    schedule 04.11.2020    source источник


Ответы (1)


Ключ в вашем JWK закодирован в base64 (на самом деле, base64url с опущенным отступом).

Если вы декодируете это значение J3SQ0IjwlJnJwu0EadenLg, вы получите следующие байты:

 27 74 90 D0 88 F0 94 99 C9 C2 ED 04 69 D7 A7 2E 

Это 16 байт, то есть 128 бит. Длина ключа правильная, вам просто нужно добавить дополнительный шаг декодирования base64 перед использованием ключа.

person Robby Cornelissen    schedule 04.11.2020
comment
Хм. Я подозревал это, но когда я выполнял декодирование base64, я получал 7-байтовые выходные данные... может быть, это из-за разницы между base64 и base64url? Я посмотрю, что я могу сделать с расшифровкой этого, и опубликую, когда я что-нибудь узнаю (или добьюсь успеха). Спасибо. - person IceMetalPunk; 04.11.2020
comment
Ах-ха! Оказывается, метод декодирования base64, который я использовал (встроенный в язык), предполагает, что вы декодируете строки с нулевым завершением, поэтому, когда ключ декодируется, чтобы включить нулевой байт, он сломался. Я заменил его другой реализацией base64, и теперь он работает! Спасибо за помощь! - person IceMetalPunk; 04.11.2020