В криптографических системах подпись и шифрование решают разные задачи, хотя часто используются вместе и могут казаться взаимозаменяемыми. В контексте библиотеки Iron (Node.js / JavaScript) это различие особенно важно, потому что Iron реализует не просто «шифрование данных», а механизм защиты, объединяющий конфиденциальность, целостность и аутентичность.
Шифрование предназначено для обеспечения конфиденциальности данных. Его цель — сделать информацию недоступной для стороннего наблюдателя без ключа расшифровки.
При использовании симметричного шифрования (что характерно для Iron) происходит следующее:
Типичная схема:
plaintext → encrypt(key) → ciphertext
ciphertext → decrypt(key) → plaintext
Главная задача — скрыть содержимое.
Однако само по себе шифрование не гарантирует:
Именно здесь возникает необходимость подписи.
Подпись предназначена для проверки целостности и подлинности данных.
Она отвечает на два вопроса:
В отличие от шифрования, подпись не скрывает содержимое.
Принцип работы:
data → hash → sign(private_key) → signature
И проверка:
data + signature → verify(public_key)
Подпись обеспечивает:
Но не обеспечивает конфиденциальность.
Причина путаницы проста: и шифрование, и подпись используют криптографические ключи и математические преобразования данных.
Однако их цели противоположны:
| Механизм | Цель | Результат |
|---|---|---|
| Шифрование | Скрыть данные | Нечитаемый текст |
| Подпись | Проверить подлинность | Проверочная метка |
В реальных системах они часто комбинируются: сначала подписывают, затем шифруют или наоборот.
Библиотека Iron в JavaScript реализует механизм sealed data — «запечатанных данных».
Он объединяет сразу три свойства:
Вместо раздельного использования подписи и шифрования Iron использует единый процесс:
seal(data, password) → protected string
unseal(protected string, password) → data
При вызове Iron.seal() данные проходят несколько
этапов:
Исходный объект преобразуется в строку (обычно JSON).
{ user: "alice" } → '{"user":"alice"}'
Из пароля и параметров создаётся криптографический ключ.
Используются:
Это важно: один и тот же пароль не используется напрямую.
Сериализованные данные шифруются симметричным алгоритмом (например, AES).
Результат:
encrypted_payload
Далее формируется HMAC — криптографическая подпись.
Она рассчитывается на основе:
Это обеспечивает защиту от подмены.
Iron объединяет все части:
В результате получается строка:
iron-sealed-string
Важный момент: Iron не использует классическую «подпись с публичным ключом».
Вместо этого применяется HMAC (Keyed-Hash Message Authentication Code).
| Тип | Ключ | Проверка |
|---|---|---|
| Подпись | приватный / публичный | асимметричная |
| HMAC (Iron) | общий секрет | симметричная |
Использование HMAC вместо RSA/ECDSA объясняется задачами библиотеки:
Iron ориентирован на серверные приложения Node.js, а не на PKI-схемы.
Если изменить даже один символ в sealed строке Iron:
Это ключевая защита от атак типа tampering.
В классической криптографии можно:
В Iron эти процессы объединены в один механизм, потому что:
Разделение подписи и шифрования важно понимать при проектировании систем.
Распространённое заблуждение — считать, что Iron это просто «шифрование JSON».
На самом деле:
seal(data):
json = serialize(data)
key = deriveKey(password)
encrypted = encrypt(json, key)
mac = hmac(encrypted, key)
return encode(encrypted, mac, salt)
unseal(token):
decode parts
key = deriveKey(password)
verify mac
decrypt encrypted
return deserialize
Понимание различий помогает:
Например:
В Iron оба механизма работают вместе:
Именно это отличает Iron от простых реализаций encryption-only или signature-only подходов.