javascript42
Главная
Все учебники
Блог
Учебник Jose
Введение в Jose и экосистему JavaScript-криптографии
Что такое Jose и зачем он нужен
Стандарты JWS, JWE, JWK, JWA, JWT — общая картина
Место Jose среди других библиотек: jsonwebtoken, node-jose, jose4j
Установка и настройка окружения
Поддерживаемые среды: Node.js, Deno, браузер, Edge Runtime
Структура пакета и точки входа
Криптографические основы
Симметричное и асимметричное шифрование
Хэш-функции и HMAC
Цифровые подписи: принципы работы
Алгоритмы семейства RSA
Алгоритмы семейства EC (эллиптические кривые)
Алгоритмы семейства OKP: Ed25519, Ed448, X25519, X448
AES и его режимы работы в контексте Jose
PBKDF2, HKDF и производные ключи
Понятие безопасной случайности и её источники в разных средах
Ключи и JWK
Анатомия JSON Web Key
Параметры JWK: kty, use, key_ops, alg, kid, x5c, x5t
Генерация ключей: generateKeyPair и generateSecret
Импорт ключей: importSPKI, importPKCS8, importX509, importJWK
Экспорт ключей: exportSPKI, exportPKCS8, exportJWK
Преобразование между форматами PEM и JWK
Работа с сертификатами X.509
JWK Set: структура и назначение
Создание и разбор JWKS вручную
Загрузка удалённого JWKS: createRemoteJWKSet
Кэширование и ротация ключей в createRemoteJWKSet
Локальный JWKS: createLocalJWKSet
Подбор ключа по kid, alg, use при верификации
Генерация и проверка отпечатков ключей: calculateJwkThumbprint
Встроенные криптографические примитивы: subtle crypto под капотом
JSON Web Token
Структура JWT: header, payload, signature
Зарегистрированные claims: iss, sub, aud, exp, nbf, iat, jti
Приватные и публичные claims
Подписанный JWT против зашифрованного JWT
Создание JWT: SignJWT
Обязательные и опциональные параметры при подписании
Установка времени жизни токена: setExpirationTime
setIssuedAt, setNotBefore, setIssuer, setSubject, setAudience, setJti
Верификация JWT: jwtVerify
Параметры верификации: algorithms, audience, issuer, clockTolerance
Обработка истёкших токенов
Проверка nbf и iat
Вложенные JWT
JWT с несколькими получателями
Распространённые ошибки при работе с JWT и их причины
JSON Web Signature
Компактная сериализация JWS
JSON-сериализация JWS: Flattened и General
Заголовки JWS: alg, kid, jwk, x5c, crit, b64
Создание подписи: CompactSign
Создание подписи с JSON-сериализацией: FlattenedSign, GeneralSign
Верификация компактного JWS: compactVerify
Верификация Flattened JWS: flattenedVerify
Верификация General JWS: generalVerify
Unprotected-заголовки и их безопасность
Параметр b64 и неприкреплённый payload
Множественные подписи в General JWS
Критические заголовки: параметр crit
JSON Web Encryption
Архитектура JWE: пять компонентов
Алгоритмы обёртки ключей: RSA-OAEP, ECDH-ES, AES-KW, PBES2, dir
Алгоритмы шифрования содержимого: AES-GCM, AES-CBC с HMAC
Компактная сериализация JWE
JSON-сериализация JWE: Flattened и General
Заголовки JWE: alg, enc, zip, kid, epk, apu, apv, p2s, p2c
Создание зашифрованного токена: CompactEncrypt
Создание Flattened JWE: FlattenedEncrypt
Создание General JWE: GeneralEncrypt
Расшифровка компактного JWE: compactDecrypt
Расшифровка Flattened JWE: flattenedDecrypt
Расшифровка General JWE: generalDecrypt
Сжатие payload: параметр zip
JWE с несколькими получателями в General-сериализации
ECDH-ES и эфемерные ключи
Прямое шифрование ключом: alg "dir"
Парольное шифрование: PBES2-HS256+A128KW и другие
Зашифрованный JWT
Отличие зашифрованного JWT от подписанного
Создание зашифрованного JWT: EncryptJWT
Расшифровка и верификация: jwtDecrypt
Параметры jwtDecrypt: issuer, audience, clockTolerance
Вложенный JWT: подпись внутри шифрования
Выбор алгоритмов для зашифрованного JWT
Алгоритмы и их применение
Семейство HMAC: HS256, HS384, HS512
Семейство RSA PKCS#1: RS256, RS384, RS512
Семейство RSA-PSS: PS256, PS384, PS512
Семейство ECDSA: ES256, ES384, ES512
EdDSA: Ed25519 и Ed448
RSA-OAEP, RSA-OAEP-256, RSA-OAEP-384, RSA-OAEP-512
ECDH-ES и ECDH-ES+AES-KW
AES Key Wrap: A128KW, A192KW, A256KW
AES-GCM Key Wrap: A128GCMKW, A192GCMKW, A256GCMKW
PBES2 и его параметры итераций
Прямое шифрование: dir
Алгоритмы контентного шифрования: A128GCM, A192GCM, A256GCM
A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
Таблица совместимости алгоритмов и типов ключей
Рекомендации по выбору алгоритмов в 2024 году
Продвинутая работа с ключами
Ротация ключей: стратегии и реализация
Управление kid при смене ключей
Кэширование JWKS и настройка времени жизни кэша
cooldownDuration и cacheMaxAge в createRemoteJWKSet
Обработка ошибок при недоступности JWKS-эндпоинта
Несколько JWKS-источников и их приоритизация
Ключи для разных окружений: dev, staging, production
Аппаратные ключи и HSM: интеграция через WebCrypto
Работа с ошибками
Иерархия ошибок в Jose
JOSEError и её подклассы
JWTExpired: обработка истёкшего токена
JWTInvalid, JWSInvalid, JWEInvalid
JOSEAlgNotAllowed и JOSENotSupported
JWKSNoMatchingKey и JWKSMultipleMatchingKeys
JWKSTimeout и JWKSInvalid
JWTClaimValidationFailed
Стратегии восстановления после ошибок
Логирование криптографических ошибок без утечки данных
Интеграция с платформами и фреймворками
Node.js: особенности и ограничения node:crypto
Браузер и Web Crypto API
Deno и его встроенная криптография
Edge Runtime: Cloudflare Workers, Vercel Edge
React Server Components и серверные действия
Next.js: защита маршрутов через JWT
Express.js: middleware для верификации токенов
Fastify и jose
Hono и Edge-окружения
Аутентификация и авторизация на практике
Схема аутентификации на основе JWT
Access token и refresh token: паттерн реализации
Хранение токенов: куки против localStorage
HttpOnly-куки и защита от XSS
Короткоживущие access-токены и их ротация
Отзыв токенов: blocklist и альтернативы
Роли и разрешения в claims
Scope-based авторизация
Делегированный доступ и on-behalf-of токены
OpenID Connect и OAuth 2.0
Место Jose в стеке OIDC
ID Token: структура и верификация
Discovery-документ и получение JWKS URI
Верификация подписи ID Token через JWKS
at_hash и c_hash: верификация токенов доступа
Параметр nonce и защита от повторных атак
Client Assertion: private_key_jwt
DPoP токены: структура и верификация
JAR: подписанный запрос авторизации
JARM: подписанный ответ авторизации
Безопасность
Атаки на JWT: alg:none, key confusion, header injection
Почему нельзя доверять заголовку alg без ограничений
Белый список алгоритмов в Jose
Атаки на JWKS: подмена ключа через jku и x5u
Уязвимости RSA PKCS#1 v1.5 и почему стоит использовать OAEP
Тайминговые атаки и константное сравнение
Выбор длины ключей и срока действия
Короткие секреты и атаки перебором на HMAC
Безопасная генерация jti и предотвращение replay-атак
Проверка iss и aud как обязательный шаг
Принцип минимальных claims
Аудит зависимостей и отслеживание CVE в Jose
Тестирование
Стратегия тестирования криптографического кода
Мокирование ключей и токенов в unit-тестах
Генерация тестовых ключевых пар
Создание токенов с истёкшим сроком для тестирования
Тестирование граничных случаев: clockTolerance, nbf
Интеграционное тестирование JWKS-эндпоинта
Fuzzing-тестирование парсеров токенов
Проверка совместимости с другими библиотеками