JWK для симметричных ключей: k

В спецификации JSON Web Key (JWK) симметричные ключи представляются типом kty: "oct", где ключ хранится как последовательность байтов в виде строки, закодированной в base64url. Основное поле для такого ключа — k, содержащее секретный материал.

{
  "kty": "oct",
  "k": "base64url-encoded-secret"
}

Структура симметричного JWK

Для симметричных алгоритмов используется один и тот же секрет для шифрования и расшифрования или подписи и проверки. В JWK это отражается минимальным набором обязательных полей:

  • kty: всегда "oct" для симметричных ключей
  • k: секретный ключ в формате base64url
  • alg (опционально): предполагаемый алгоритм использования ключа
  • key_ops (опционально): допустимые операции (например ["encrypt", "decrypt"])
  • ext: признак извлекаемости ключа

Поле k: представление секретного ключа

Поле k содержит не строку в привычном смысле, а бинарные данные, закодированные в base64url без padding.

Особенности формата:

  • используется base64url (не стандартный base64)
  • символы + и / заменяются на - и _
  • отсутствует символ =
  • представляет байтовый массив фиксированной или переменной длины

Пример:

{
  "kty": "oct",
  "k": "GawgguFyGrWKav7AX4VKUg"
}

Генерация симметричного ключа в Jsrsasign

В библиотеке Jsrsasign симметрические ключи можно генерировать через криптографические утилиты KJUR.crypto.

Пример генерации случайного ключа:

const keyObj = new KJUR.crypto.KeyObject();
const rawKey = KEYUTIL.getKey("AES", 256); // создание 256-битного ключа
const jwk = KEYUTIL.getJWKFromKey(rawKey);

В результате получается объект JWK:

{
  "kty": "oct",
  "k": "base64url-encoded-key",
  "alg": "A256GCM"
}

Создание JWK вручную

Симметричный ключ может быть создан вручную при условии корректного base64url кодирования.

Пример:

const raw = "supersecretkeymaterial";
const b64 = Buffer.from(raw).toString("base64")
  .replace(/\+/g, "-")
  .replace(/\//g, "_")
  .replace(/=+$/, "");

const jwk = {
  kty: "oct",
  k: b64
};

Использование JWK в Jsrsasign

Jsrsasign поддерживает работу с симметричными ключами через унифицированный API KEYUTIL.

Импорт JWK:

const key = KEYUTIL.getKey(jwk);

После преобразования ключ может использоваться в криптографических операциях.


HMAC с использованием k ключа

Одно из основных применений симметричных JWK — HMAC-подписи.

const hmac = new KJUR.crypto.Mac({ alg: "HmacSHA256", pass: key });
hmac.updateString("message data");
const signature = hmac.doFinal();

Здесь ключ, извлечённый из k, используется как секрет для HMAC.


AES шифрование с симметричным JWK

Для алгоритмов шифрования, таких как AES, ключ из JWK применяется напрямую.

const cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  key: key
});

const encrypted = cipher.encrypt("plaintext message");
const decrypted = cipher.decrypt(encrypted);

Валидация параметра k

При работе с симметричными JWK необходимо учитывать строгие требования:

1. Корректная длина ключа

  • AES-128 → 16 байт
  • AES-192 → 24 байта
  • AES-256 → 32 байта

Несоответствие длины приводит к ошибкам криптографических операций.


2. Base64url без padding

Частая ошибка — использование обычного base64:

  • недопустимы символы =
  • недопустимы + и /

3. Соответствие алгоритму

Поле alg должно согласовываться с размером ключа:

  • A128GCM
  • A256GCM
  • HS256, HS512 для HMAC

Извлечение ключа из JWK

Jsrsasign предоставляет унифицированный механизм:

const keyObj = KEYUTIL.getKey(jwk);

Внутренне происходит:

  • декодирование k
  • преобразование в бинарный массив
  • создание криптографического объекта

Преобразование ключа обратно в JWK

При экспорте ключа:

const jwkOut = KEYUTIL.getJWKFromKey(keyObj);

Результат включает:

  • kty: "oct"
  • k — base64url строка
  • дополнительные параметры при наличии

Использование key_ops

Поле key_ops ограничивает допустимые операции:

{
  "kty": "oct",
  "k": "base64urlkey",
  "key_ops": ["encrypt", "decrypt"]
}

Возможные операции:

  • encrypt
  • decrypt
  • sign
  • verify

Хотя для симметричных ключей чаще используется HMAC и AES, ограничения операций помогают контролировать контекст использования.


Безопасность симметричных JWK

Использование поля k связано с прямым хранением секретного материала, что требует строгого контроля:

1. Недопустимо хранение в открытом виде

JWK с k нельзя размещать в публичных репозиториях без защиты.

2. Ключ должен быть случайным

Использование предсказуемых строк снижает криптографическую стойкость.

3. Разделение ключей

Один и тот же k не должен использоваться для разных алгоритмов (например, AES и HMAC одновременно).


Пример полного цикла работы

Создание ключа:

const rawKey = KJUR.crypto.Util.getRandomHexOfNbytes(32);
const b64 = hextob64u(rawKey);

const jwk = {
  kty: "oct",
  k: b64,
  alg: "A256GCM"
};

Использование:

const key = KEYUTIL.getKey(jwk);

const cipher = new KJUR.crypto.Cipher({
  alg: "AES",
  key: key
});

const encrypted = cipher.encrypt("data");

Обратное преобразование:

const exported = KEYUTIL.getJWKFromKey(key);

Взаимодействие с другими стандартами

Симметричные JWK тесно связаны с:

  • JWE (JSON Web Encryption)
  • JWS (JSON Web Signature)
  • JWA (JSON Web Algorithms)

Поле k является фундаментом для:

  • HMAC-SHA алгоритмов (JWS)
  • AES-GCM / AES-CBC (JWE)

Типичные ошибки при работе с k

1. Использование base64 вместо base64url

Приводит к невозможности декодирования ключа.

2. Несоответствие длины ключа алгоритму

Особенно критично для AES.

3. Потеря данных при сериализации

Некорректная обработка строки k при JSON.stringify может нарушить формат.


Особенности реализации Jsrsasign

В Jsrsasign работа с k происходит через единый слой абстракции:

  • KEYUTIL — преобразование ключей
  • KJUR.crypto.Mac — HMAC операции
  • KJUR.crypto.Cipher — симметричное шифрование

Библиотека автоматически определяет:

  • тип ключа (oct)
  • алгоритм использования
  • формат входных данных

Представление ключа в памяти

После декодирования k превращается в:

  • массив байтов (Uint8Array-подобная структура)
  • или внутренний объект CryptoJS/Jsrsasign

Этот слой никогда не должен быть сериализован обратно без необходимости.


Ограничения JWK с k

  • отсутствует асимметрия (один ключ для всех операций)
  • невозможность публичного распространения
  • необходимость синхронизации между сторонами

Практическая роль k в архитектуре безопасности

Симметричные JWK применяются в:

  • сервер-сервер коммуникации
  • API подписи запросов
  • временные токены
  • локальное шифрование данных

Ключевой аспект — единый секретный источник, представленный в стандартизированном JSON формате через k.