Кальтер / Блог

Sign-In with Ethereum: как проверить домен, nonce и срок сообщения

Разбери обязательные поля SIWE, сверку origin и одноразовость nonce; expiration-time необязателен, а проверка подписи остаётся отдельным этапом.

Материал подготовлен с помощью ИИ. Источники, учебные примеры и расчёты проверены редакцией перед публикацией.

Условная схема SIWE-входа: проверка domain/origin, nonce и времени перед сессией. expiration-time необязателен; подпись не разрешает расход средств и не защищает от фишингового сайта.
Условная схема SIWE-входа: проверка domain/origin, nonce и времени перед сессией. expiration-time необязателен; подпись не разрешает расход средств и не защищает от фишингового сайта.

Подпись SIWE — это способ войти в сервис сообщением кошелька. Она не равна транзакции в сети и сама по себе не выдаёт контракту allowance. При проверке сообщения важно сопоставить домен и origin, проверить nonce и время, а не просто увидеть зелёный статус «signature valid».

Разбери поля по обязательности

ERC-4361 определяет SIWE как off-chain authentication. В формате обязательны domain, nonce и issued-at; Expiration Time — optional. Стандарт рекомендует relying party проверять домен и схему относительно ожидаемого origin, поля и подпись, а уникальный nonce используется против повторного предъявления сообщения (ERC-4361). Это требования формата и интеграции, не гарантия безопасности конкретного сайта.

Поле Требование Что сверяет сервис Типичная ошибка
domain обязательный; scheme в строке перед domain optional сверяется с ожидаемым origin; если scheme присутствует, она тоже должна совпадать принимается чужой домен или неучтённая scheme
nonce REQUIRED выдан сервером, ожидаемый и ещё не использованный старый nonce можно предъявить снова
issued-at REQUIRED допустимая временная политика сервиса отсутствует или вне допустимого окна
expiration-time OPTIONAL если задан, сообщение ещё не истекло считать поле обязательным или игнорировать его наличие

Пройди пример как проверяющий

Учебное сообщение:

example.com wants you to sign in with your Ethereum account:
0x1111111111111111111111111111111111111111

Sign in to Example only.

URI: https://example.com/login
Version: 1
Chain ID: 1
Nonce: a7F3k9Q2
Issued At: 2026-11-01T10:00:00Z

Здесь намеренно нет Expiration Time. Его отсутствие само по себе не нарушает формат: поле необязательное. Разработчик сервиса всё равно может установить ограниченное окно по своей политике, но должен применять его последовательно. Если пользователь пришёл с https://example.com, а сообщение говорит evil.example, остановись — правильная подпись под чужим сообщением не делает origin ожидаемым.

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

Сверь сообщение с ожидаемым origin https://example.com.
Отметь обязательные поля и проверь, что необязательное expiration-time может отсутствовать.
Не утверждай, что подпись криптографически верна, пока её не проверил код.
Скажи, можно ли повторно использовать этот nonce по приведённой серверной записи.
Сообщение: [..]  Запись nonce: [fresh/consumed]

Ожидаемый учебный результат для примера: «domain согласуется с origin; nonce синтаксически присутствует, но одноразовость надо подтвердить состоянием сервера; issued-at указан; expiration-time отсутствует и это допустимо по формату; подпись ещё надо проверить криптографически». Это не аудит SIWE-библиотеки.

В реальной интеграции после успешной проверки подписи пометь nonce использованным атомарно и выдавай сессию только после полной серверной валидации. Не трактуй текст statement как набор разрешений и не подписывай непонятное сообщение. Для общего хранения ключа и подключения кошелька смотри руководство по кошельку; SIWE здесь — только входная схема.