MAC (Message Authentication Code) — это криптографический механизм, предназначенный для проверки целостности и подлинности сообщения при использовании общего секретного ключа. Основная идея заключается в том, что отправитель и получатель заранее обладают одинаковым секретом, который используется для вычисления кода аутентификации.
Формально MAC представляет собой функцию:
[ MAC = f(K, M)]
где:
Любое изменение сообщения или ключа приводит к изменению MAC.
В контексте JavaScript-библиотеки SJCL MAC чаще всего реализуется через HMAC (Hash-based Message Authentication Code), например на базе SHA-256:
var key = sjcl.random.randomWords(8);
var message = "Hello world";
var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var mac = hmac.encrypt(message);
Ключевая особенность MAC заключается в симметричности: один и тот же ключ используется и для генерации, и для проверки.
Проверка выполняется повторным вычислением:
var hmac2 = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var valid = sjcl.bitArray.equal(
hmac2.encrypt(message),
mac
);
Если MAC совпадает — сообщение считается подлинным и неизменённым.
Основное ограничение MAC связано с моделью доверия. Так как ключ общий, обе стороны обладают одинаковыми полномочиями на создание валидной подписи. Это приводит к фундаментальным свойствам:
MAC решает задачу «сообщение не было изменено», но не решает задачу «кто именно его создал» в криптографически доказуемом смысле.
Цифровая подпись основана на асимметричной криптографии, где используется пара ключей:
Подпись вычисляется с использованием приватного ключа:
[ Signature = Sign(SK, M)]
Проверка выполняется публичным ключом:
[ Verify(PK, M, Signature)]
В отличие от MAC, здесь ключи не совпадают.
SJCL поддерживает схемы цифровой подписи, например RSA или DSA-подобные конструкции (в зависимости от конфигурации и подключённых модулей).
Пример логики подписи:
var keys = sjcl.ecc.elGamal.generateKeys(256);
var message = "Important message";
// Подпись приватным ключом
var signature = keys.sec.sign(sjcl.hash.sha256.hash(message));
// Проверка публичным ключом
var isValid = keys.pub.verify(
sjcl.hash.sha256.hash(message),
signature
);
Здесь используется предварительное хеширование сообщения, что является стандартной практикой для цифровых подписей.
Разница между MAC и цифровой подписью определяется не алгоритмом, а моделью ключей.
MAC:
Цифровая подпись:
MAC не предназначен для публичной проверки. Если передать MAC третьей стороне, она не сможет определить, кто его создал, так как ключ известен только участникам канала.
Цифровая подпись, напротив, может быть проверена любым обладателем публичного ключа без раскрытия секретов.
Это делает цифровую подпись пригодной для:
Свойство non-repudiation достигается только в асимметричной криптографии.
В MAC любая сторона, обладающая ключом, может создать валидный код, поэтому доказать авторство невозможно.
В цифровой подписи ситуация иная: приватный ключ известен только владельцу, и математическая корректность подписи связывает её исключительно с ним.
MAC значительно быстрее цифровых подписей.
Причины:
Цифровая подпись:
MAC:
Цифровая подпись:
MAC применяется в случаях:
Цифровая подпись применяется:
| Свойство | MAC | Цифровая подпись |
|---|---|---|
| Тип ключей | симметричный | асимметричный |
| Проверка третьими лицами | невозможна | возможна |
| Скорость | высокая | ниже |
| Подтверждение авторства | отсутствует | присутствует |
| Масштабируемость доверия | ограничена | высокая |
В SJCL MAC обычно реализуется через HMAC-модуль поверх хеш-функций (SHA-1, SHA-256). Это делает его удобным для:
Цифровые подписи в SJCL опираются на модуль эллиптической криптографии или RSA-реализации и применяются там, где требуется независимая проверка подлинности без обмена секретом.
Разделение этих механизмов в библиотеке отражает фундаментальное различие криптографических моделей: симметричная аутентификация против асимметричного доказательства происхождения данных.