Подпись сообщений и вход без пароля (SIWE)

Подпись сообщения доказывает владение адресом без транзакции и газа. Основа входа без пароля — Sign-In with Ethereum.

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

Иногда нужно доказать «я — владелец этого адреса», но без записи в блокчейн: для входа на сайт, доступа к приватному API, подтверждения личности. Транзакция тут избыточна (стоит газ, попадает on-chain). Подпись сообщения решает это бесплатно и приватно.

Как это работает в три шага

  1. Сервер даёт сообщение с уникальным nonce (одноразовым числом), чтобы подпись нельзя было переиспользовать.
  2. Пользователь подписывает его кошельком (окно «Sign» — без газа).
  3. Сервер проверяет подпись: восстанавливает из неё адрес и сверяет с заявленным. Совпало — выдаёт сессию.
// фронт: попросить подпись
const message = `Войти на example.com\nnonce: 8f3a...`;
const signature = await signer.signMessage(message);
// отправить { address, message, signature } на сервер для проверки

Sign-In with Ethereum (SIWE)

SIWE (EIP-4361) — стандарт формата такого сообщения для входа: домен, адрес, nonce, срок действия, сеть. Стандарт нужен, чтобы кошельки показывали понятный текст, а не сырую кашу, и чтобы защититься от фишинга (видно, на какой домен вы входите):

example.com wants you to sign in with your Ethereum account:
0x71C7...976F

URI: https://example.com
Version: 1
Chain ID: 1
Nonce: 8f3a9c2b
Issued At: 2024-01-01T00:00:00Z

Почему подпись безопаснее пароля

  • Нет пароля, который можно украсть с сервера — сервер хранит лишь адрес.
  • Подпись не передаёт приватный ключ; восстановить ключ из подписи невозможно.
  • nonce делает подпись одноразовой — перехват не даёт повторного входа.

Как работает под капотом

Кошелёк хеширует сообщение (с префиксом по стандарту personal_sign, чтобы его нельзя было выдать за транзакцию) и подписывает хеш приватным ключом по алгоритму ECDSA. Подпись — это три числа (r, s, v). Сервер применяет ecrecover: из хеша сообщения и подписи математически восстанавливает публичный адрес подписавшего. Если он равен заявленному — подпись подлинна. Критично: подписывать на сервере проверяют именно то же сообщение с тем nonce, иначе возможен replay-атака.

Частые ошибки

  • Подпись без nonce. Тогда одну подпись можно переиспользовать (replay). Nonce обязателен.
  • Не показывать домен в сообщении. Пользователь не поймёт, куда входит — поле для фишинга.
  • Путать подпись с транзакцией. Подпись бесплатна и не идёт on-chain; не пугайте пользователя «комиссией».

Итоги

  • Подпись сообщения доказывает владение адресом без газа и транзакции.
  • SIWE (EIP-4361) — стандарт входа: понятный текст, домен, nonce, срок.
  • Сервер проверяет подпись через восстановление адреса; nonce защищает от replay.
Проверьте себя
1. Чем подпись сообщения отличается от транзакции?
AПодпись стоит больше газа
BПодпись бесплатна, не идёт on-chain и не требует газа
CПодпись меняет состояние контракта
DЭто одно и то же
2. Зачем в сообщении для входа нужен nonce?
AДля красоты
BЧтобы подпись была одноразовой и её нельзя было переиспользовать (replay)
CЧтобы оплатить газ
DЧтобы сменить сеть
3. Как сервер проверяет, что подпись принадлежит заявленному адресу?
AЗапрашивает приватный ключ
BВосстанавливает адрес из подписи (ecrecover) и сверяет
CЗвонит в MetaMask
DЧитает баланс