ECDSA: эллиптические кривые P-256, P-384, P-521

ECDSA (Elliptic Curve Digital Signature Algorithm) основан на свойствах эллиптических кривых над конечными полями. В отличие от классических схем RSA, где безопасность опирается на факторизацию больших чисел, здесь используется сложность задачи дискретного логарифмирования на эллиптических кривых.

В контексте Web Crypto API ECDSA реализуется через интерфейс SubtleCrypto, где работа с ключами и подписями полностью асинхронна и выполняется в защищённом контексте браузера.

Ключевая идея схемы:

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

Кривые P-256, P-384, P-521

В Web Crypto API поддерживаются стандартизированные кривые семейства NIST:

  • P-256 (secp256r1)
  • P-384 (secp384r1)
  • P-521 (secp521r1)

Каждая кривая отличается уровнем криптографической стойкости и размером ключа.

P-256

Наиболее часто используемая кривая. Баланс между производительностью и безопасностью. Используется в TLS, JWT, мобильных приложениях и большинстве браузерных сценариев.

  • длина ключа: 256 бит
  • эквивалент безопасности: ~128 бит симметрического шифрования
  • оптимизирована для быстрого выполнения операций

P-384

Более высокий уровень безопасности, применяемый в корпоративных и государственных системах.

  • длина ключа: 384 бит
  • эквивалент безопасности: ~192 бит
  • более медленная генерация и подпись по сравнению с P-256

P-521

Максимальный уровень безопасности среди поддерживаемых Web Crypto API кривых.

  • длина ключа: 521 бит
  • эквивалент безопасности: ~256 бит
  • используется редко из-за высокой вычислительной стоимости

Генерация ключевой пары ECDSA

В Web Crypto API ключи создаются через crypto.subtle.generateKey. Для ECDSA требуется указать алгоритм, имя кривой и назначение ключей.

const keyPair = await crypto.subtle.generateKey(
  {
    name: "ECDSA",
    namedCurve: "P-256"
  },
  true,
  ["sign", "verify"]
);

Параметры:

  • name: "ECDSA" — использование алгоритма цифровой подписи
  • namedCurve — выбор кривой (P-256, P-384, P-521)
  • extractable — возможность экспорта ключа
  • keyUsages — допустимые операции (подпись и проверка)

Результат содержит:

  • privateKey
  • publicKey

Формат данных для подписи

ECDSA работает с бинарными данными. Перед подписью строковые данные преобразуются в ArrayBuffer через TextEncoder.

const encoder = new TextEncoder();
const data = encoder.encode("сообщение для подписи");

Создание цифровой подписи

Подпись выполняется приватным ключом через crypto.subtle.sign.

const signature = await crypto.subtle.sign(
  {
    name: "ECDSA",
    hash: { name: "SHA-256" }
  },
  keyPair.privateKey,
  data
);

Особенности:

  • обязательное использование хэш-функции (SHA-256, SHA-384 или SHA-512)
  • результат — бинарная подпись в формате ArrayBuffer
  • подпись зависит как от данных, так и от выбранного алгоритма хэширования

Проверка подписи

Публичный ключ используется для верификации через crypto.subtle.verify.

const isValid = await crypto.subtle.verify(
  {
    name: "ECDSA",
    hash: { name: "SHA-256" }
  },
  keyPair.publicKey,
  signature,
  data
);

Результат:

  • true — подпись корректна
  • false — данные изменены или подпись недействительна

Взаимосвязь кривой и хэш-функции

ECDSA требует согласованности между размером кривой и хэш-функцией:

  • P-256 → SHA-256
  • P-384 → SHA-384
  • P-521 → SHA-512

Несоответствие может привести к ошибке выполнения или снижению криптографической корректности.


Экспорт и импорт ключей

Web Crypto API позволяет экспортировать ключи в стандартизированных форматах.

Экспорт публичного ключа

const exported = await crypto.subtle.exportKey(
  "spki",
  keyPair.publicKey
);

Экспорт приватного ключа

const exportedPrivate = await crypto.subtle.exportKey(
  "pkcs8",
  keyPair.privateKey
);

Форматы:

  • SPKI — публичный ключ
  • PKCS#8 — приватный ключ

Оба формата представляют бинарные структуры ASN.1.


Импорт ключей

Импорт выполняется через crypto.subtle.importKey.

const publicKey = await crypto.subtle.importKey(
  "spki",
  exported,
  {
    name: "ECDSA",
    namedCurve: "P-256"
  },
  true,
  ["verify"]
);
const privateKey = await crypto.subtle.importKey(
  "pkcs8",
  exportedPrivate,
  {
    name: "ECDSA",
    namedCurve: "P-256"
  },
  true,
  ["sign"]
);

Формат подписи ECDSA в Web Crypto API

Подпись возвращается в формате ASN.1 DER, содержащем два числа:

  • r
  • s

Это стандартное представление ECDSA-подписи, отличающееся от “сырых” форматов, используемых в некоторых криптографических библиотеках.


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

ECDSA в Web Crypto API работает внутри изолированной криптографической подсистемы браузера:

  • приватные ключи недоступны JavaScript напрямую при extractable: false
  • операции выполняются в защищённом контексте
  • ключи могут быть привязаны к конкретному происхождению (origin)

Сильные стороны модели:

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

Производительность кривых

Различия в вычислительной стоимости:

  • P-256 — минимальная нагрузка, подходит для частых подписей (JWT, API-запросы)
  • P-384 — компромисс между безопасностью и скоростью
  • P-521 — заметное снижение производительности при массовых операциях

В браузерных приложениях P-256 остаётся стандартным выбором из-за оптимизации аппаратного ускорения в большинстве современных платформ.


Использование в протоколах

ECDSA на базе Web Crypto API применяется в:

  • JWT (JSON Web Token) с алгоритмами ES256, ES384, ES512
  • TLS-цепочках сертификатов
  • WebAuthn (аутентификация без паролей)
  • цифровой подписи сообщений API

Каждый из этих сценариев опирается на одну и ту же модель: приватный ключ остаётся на стороне клиента или защищённого хранилища, публичный используется для проверки на стороне сервера.


Сравнение кривых с точки зрения применения

P-256:

  • веб-приложения
  • мобильные клиенты
  • высокочастотные подписи

P-384:

  • банковские системы
  • государственные сервисы
  • повышенные требования к стойкости

P-521:

  • специализированные криптографические системы
  • долгосрочное хранение данных с максимальной защитой

Типичные ошибки при работе с ECDSA в Web Crypto API

  • использование неподдерживаемой кривой в конкретной среде
  • несоответствие хэш-функции выбранной кривой
  • попытка подписывать данные без предварительного хэширования через API
  • неправильный формат при импорте ключей (SPKI/PKCS#8)
  • попытка синхронного выполнения криптографических операций

Структура потоков данных в подписи

Процесс можно разложить на последовательность:

  1. преобразование данных в бинарный формат
  2. вычисление хэша (SHA-256/384/512)
  3. применение приватного ключа к хэшу
  4. генерация пары чисел (r, s)
  5. кодирование подписи в DER-формат

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


Влияние выбора кривой на архитектуру приложения

Выбор P-256, P-384 или P-521 влияет не только на безопасность, но и на:

  • задержки ответа API
  • нагрузку на клиентские устройства
  • размер передаваемых подписей
  • совместимость с внешними системами

В браузерных приложениях баланс обычно смещён в сторону P-256 из-за аппаратной поддержки и предсказуемой производительности.


Асинхронная модель Web Crypto API

Все операции ECDSA выполняются асинхронно через Promise:

  • генерация ключей
  • подпись
  • проверка
  • импорт и экспорт

Это исключает блокировку основного потока браузера и обеспечивает стабильность интерфейса при криптографических вычислениях.