javascript

SecretAuth – UX-решение для авторизации посредством приватного ключа

  • суббота, 4 июля 2026 г. в 00:00:05
https://habr.com/ru/articles/1055364/

Мир сильно изменился с начала 21 века. В том числе, что касается систем авторизации. Мы продвинулись от авторизации через обычный логин и пароль к использованию централизованных сервисов вроде Google и Apple. Но так ли хорошо это для пользователя? И можно ли сказать, что его данные принадлежат ему?

Давайте я покажу вам интересную вещь. SecretAuth – UX-решение для авторизации приватным ключом. Конечно, ничего нового в подписании данных приватным ключом, а потом в проверке их через публичный ключ – нет. Вы абсолютно правы.

Дело в том, что это UX-решение, и сейчас вы поймёте, о чём речь.

Чаще всего у пользователя уже есть приватный ключ, например в крипто-кошельке. Либо он может использовать стандарт WebAuthn, когда приватный ключ генерируется и хранится в браузере. Либо человек сам может сгенерировать приватный ключ и хранить его в текстовом файле. Суть этого UX-стандарта – дать возможность человеку авторизоваться приватным ключом и не светить свои данные, email, телефон и прочее. На сервере просто проверить подписанные данные и всё.

Примеры: что уходит на сервер

Сервер сначала выдаёт challenge:

{

 "domain": "example.com",

 "nonce": "a1b2c3d4e5f6789012345678abcdef01",

 "exp": 1719667500

}

Клиент подписывает сообщение:

example.com wants you to prove your signing key:

nonce: a1b2c3d4e5f6789012345678abcdef01

exp: 1719667500

После подписи на сервер отправляется proof — он меняется в зависимости от, что используется (кошелёк, свой ключ, passkey).

Кошелёк (Ethereum):

{

 "message": "example.com wants you to prove your signing key:\n\nnonce: a1b2c3d4e5f6789012345678abcdef01\nexp: 1719667500",

 "signature": { "value": "0x…" },

 "pubKey": {

   "algorithm": "secp256k1",

   "source": "ethereum",

   "value": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",

   "encoding": "hex"

 }

}

Свой ключ (сгенерированный или из файла):

{

 "message": "example.com wants you to prove your signing key:\n\nnonce: a1b2c3d4e5f6789012345678abcdef01\nexp: 1719667500",

 "signature": { "value": "base64…", "encoding": "base64" },

 "pubKey": {

   "algorithm": "Ed25519",

   "source": "raw",

   "value": "base64-public-key…",

   "encoding": "base64"

 }

}

Passkey (WebAuthn):

{

 "message": "example.com wants you to prove your signing key:\n\nnonce: a1b2c3d4e5f6789012345678abcdef01\nexp: 1719667500",

 "signature": {

   "value": "base64url…",

   "encoding": "base64url",

   "extension": {

     "authenticatorData": "base64url…",

     "clientDataJSON": "base64url…"

   }

 },

 "pubKey": {

   "algorithm": "ES256",

   "source": "webauthn",

   "value": "base64url-credential-id",

   "encoding": "base64url"

 }

}

Вместо выводов

Как видите, главная задача этого решения – дать человеку подписать данные для авторизации наиболее удобным ему способом

Спека: https://github.com/MaratBektemirov/SecretAuth
Реализация: https://cruzo.org/#/web3/auth