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

В задачах защиты данных на уровне приложения чаще всего требуется решить одну из двух фундаментальных задач: подтвердить целостность сообщения и удостовериться в его происхождении. Для этого в Web Crypto API используются два принципиально разных механизма — HMAC и цифровая подпись.

Несмотря на внешнее сходство (оба механизма позволяют проверить, что данные не были изменены), их криптографическая природа, модель доверия и сценарии применения различаются настолько существенно, что их корректное понимание определяет архитектуру безопасности веб-приложений.


HMAC: симметричная аутентификация сообщений

HMAC (Hash-based Message Authentication Code) основан на симметричной криптографии. Он использует общий секретный ключ для генерации и проверки кода аутентификации сообщения.

Криптографическая основа

HMAC строится поверх хеш-функции (например, SHA-256):

  • Один и тот же секретный ключ используется для:

    • генерации HMAC
    • проверки HMAC
  • Без знания ключа невозможно подделать корректный код

В Web Crypto API это реализуется через алгоритм "HMAC" с указанием хеш-функции:

const key = await crypto.subtle.generateKey(
  {
    name: "HMAC",
    hash: "SHA-256"
  },
  true,
  ["sign", "verify"]
);

Генерация и проверка HMAC

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

const signature = await crypto.subtle.sign(
  "HMAC",
  key,
  data
);

const isValid = await crypto.subtle.verify(
  "HMAC",
  key,
  signature,
  data
);

Свойства HMAC

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

Ключевая особенность модели доверия

HMAC предполагает, что обе стороны уже обладают одинаковым секретом. Это означает:

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

Цифровая подпись: асимметричная криптография

Цифровая подпись основана на асимметричных ключах:

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

Это фундаментально меняет модель безопасности.

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

В Web Crypto API используется алгоритм "RSASSA-PKCS1-v1_5" или "ECDSA":

const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSASSA-PKCS1-v1_5",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256"
  },
  true,
  ["sign", "verify"]
);

Создание подписи

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

const signature = await crypto.subtle.sign(
  "RSASSA-PKCS1-v1_5",
  keyPair.privateKey,
  data
);

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

const isValid = await crypto.subtle.verify(
  "RSASSA-PKCS1-v1_5",
  keyPair.publicKey,
  signature,
  data
);

Сравнение модели доверия

HMAC

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

Цифровая подпись

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

Принципиальное различие в безопасности

HMAC: доверие через общий секрет

Безопасность полностью зависит от сохранности одного ключа. Если он известен:

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

Таким образом HMAC обеспечивает только целостность и аутентичность в рамках закрытого канала.


Цифровая подпись: доверие через владение приватным ключом

Здесь важен факт владения приватным ключом:

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

Это создаёт модель “проверяемого происхождения”, а не просто “общего секрета”.


Производительность и вычислительная сложность

HMAC

  • быстрее
  • использует хеш-функции
  • минимальная нагрузка на CPU
  • подходит для массовых операций (например, API-запросов)

Цифровая подпись

  • существенно медленнее
  • использует сложные математические операции (RSA или эллиптические кривые)
  • требует больше ресурсов
  • предпочтительна для реже выполняемых операций (например, подпись документа)

Практические сценарии применения

Когда используется HMAC

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

Когда используется цифровая подпись

  • подтверждение авторства документа
  • распределённые системы без общего секрета
  • криптографические токены с публичной проверкой
  • блокчейн-системы и децентрализованные протоколы
  • подписание JWT в открытых инфраструктурах

Различие в масштабируемости

HMAC

Проблема масштабирования возникает при увеличении числа участников:

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

Цифровая подпись

Масштабируется естественно:

  • один приватный ключ — один подписант
  • любое количество проверяющих
  • нет необходимости в распределении секретов

Ошибки архитектурного выбора

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

Попытка использовать HMAC там, где ключи распространяются между клиентами, приводит к фундаментальной уязвимости: любой клиент становится потенциальным подписантом.


Использование цифровой подписи для внутренних быстрых проверок

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


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

Характеристика HMAC Цифровая подпись
Тип криптографии Симметричная Асимметричная
Количество ключей Один Пара
Скорость Высокая Ниже
Масштабируемость Ограниченная Высокая
Распределение доверия Общий секрет Публичная проверка
Основной риск Утечка ключа Компрометация приватного ключа

Внутренние особенности Web Crypto API

HMAC в Web Crypto

  • работает только с симметричными ключами
  • ключ создаётся как CryptoKey
  • поддерживает sign и verify

Подпись в Web Crypto

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

Криптографическая интерпретация различий

HMAC отвечает на вопрос:

“Знает ли отправитель общий секрет?”

Цифровая подпись отвечает на вопрос:

“Кто именно подписал данные?”


Итоговое различие на уровне модели безопасности

HMAC — это механизм доверия внутри замкнутой системы.

Цифровая подпись — это механизм доверия в открытой системе, где участники не обязаны доверять друг другу заранее.

Разделение этих подходов является базовым принципом проектирования безопасных протоколов в Web Crypto API и определяет архитектуру любой криптографически защищённой веб-системы.