Подпись сообщений
Ваше приложение может попросить человека подписать текстовое сообщение своим постинг- или активным ключом. Подпись подтверждает, что аккаунт принадлежит ему. Ничего не отправляется в сеть: сообщение никогда не попадает в блокчейн. Hivesigner подписывает так же, как requestSignBuffer в Hive Keychain, поэтому серверный код, который проверяет подпись Keychain, проверит и подпись Hivesigner.
Запросите подпись
Отправьте человека на https://hivesigner.com/sign-buffer с такими параметрами запроса:
| Параметр | Обязателен | Значение |
|---|---|---|
message |
Да | Точный текст для подписи. В нём должно быть что-то кроме пробелов. |
redirect_uri |
Да | Куда Hivesigner отправит результат. Смотрите Правила адреса возврата. |
authority |
Нет | posting или active, в любом регистре (Posting тоже подойдёт). Если параметра нет или он пуст, берётся posting. Любое другое значение отклоняется. |
client_id |
Нет | Аккаунт вашего приложения. Читается и clientId. С ним redirect_uri должен быть одним из адресов возврата вашего приложения. |
state |
Нет | Любое значение. Hivesigner возвращает его без изменений. |
account |
Нет | Аккаунт, от которого вы ждёте подпись. Hivesigner выбирает его, если он есть на устройстве, и не учитывает в противном случае. Читается и select_account. |
Соберите адрес через URLSearchParams, чтобы каждое значение было закодировано:
const params = new URLSearchParams({
message: 'MESSAGE',
authority: 'posting',
redirect_uri: 'REDIRECT_URI',
client_id: 'CLIENT_ID',
state: 'STATE',
});
window.location.assign(`https://hivesigner.com/sign-buffer?${params}`);
Правила адреса возврата
- Адрес возврата должен быть
https://. Обычныйhttp://работает только на петлевом адресе:localhost,127.0.0.1или[::1]. - С
client_idадрес возврата должен быть зарегистрирован на этом аккаунте приложения и сверяется так же, как при входе. Смотрите Адреса возврата. Hivesigner читает адреса возврата приложения из Hive, когда открывается запрос, и ничего не подписывает, пока их не прочитает. Если до Hive не достучаться, человек получает кнопку Повторить. - Без
client_idподойдёт любой адрес возврата, который отвечает первому правилу. Тогда Hivesigner называет запрашивающим хост этого адреса, например «HOST просит вас подписать сообщение.».
Отправляйте client_id, когда у вас есть аккаунт приложения. Тогда человек видит название и аккаунт вашего приложения. Получить подпись смогут только ваши зарегистрированные адреса возврата.
Hivesigner отклоняет запрос без сообщения, с неизвестным authority, с отсутствующим или непригодным адресом возврата, с client_id, который не является аккаунтом Hive, или с адресом возврата, не зарегистрированным на этом приложении. Человек видит «Этот запрос на подпись нельзя использовать: нужны сообщение, постинг- или активный ключ и защищённый адрес перенаправления, зарегистрированный для приложения. Вернитесь на сайт и попробуйте ещё раз.» и кнопку Сообщить о проблеме.
Что видит человек
- Заголовок с названием вашего приложения (или хостом адреса возврата) и «Перенаправит вас на HOST».
- Всё сообщение целиком, ровно в том виде, в каком оно будет подписано. Символы, которые могли бы спрятать текст или изменить его направление, показываются как коды вида
\u{200B}. - «Подписывается вашим постинг-ключом» или «Подписывается вашим активным ключом».
- Предупреждение: «Ваша подпись доказывает любому, кто её увидит, что @USERNAME подписал именно этот текст. Подписывайте только сообщение, которое понимаете.»
- Подписать и Отмена. Заблокированный аккаунт сначала спрашивает код доступа.
Запросы на подпись сообщения описывают этот экран для людей.
Что получает ваш адрес возврата
Когда человек выбирает Подписать, Hivesigner отправляет его на ваш адрес возврата с такими параметрами запроса:
| Параметр | Значение |
|---|---|
signature |
Подпись, шестнадцатеричная строка из 130 символов |
public_key |
Открытый ключ того ключа, которым подписано, вида STM... |
username |
Аккаунт, который подписал |
authority |
posting или active |
state |
Ваш state, всякий раз, когда он был в запросе (в том числе пустой) |
Hivesigner добавляет их в строку запроса вашего адреса, после ? или & и перед любым #fragment. Ваша собственная строка запроса остаётся как есть.
https://YOUR_APP/signed?signature=SIGNATURE&public_key=PUBLIC_KEY&username=USERNAME&authority=posting&state=STATE
Когда человек выбирает Отмена, Hivesigner открывает его список аккаунтов. Ваш адрес возврата не получает ничего.
Предупреждение: Открыть ваш адрес возврата с выдуманными значениями может кто угодно. Считайте каждый параметр лишь утверждением, пока ваш сервер не проверит подпись.
Проверьте подпись
Проверьте подпись на своём сервере:
- Храните на своём сервере сообщение, которое вы запрашивали, вместе с его
state. Не доверяйте копии, вернувшейся из браузера. - Посчитайте хеш сообщения: sha256 по его байтам UTF-8.
- Восстановите открытый ключ из подписи и этого хеша.
- Загрузите аккаунт из Hive. Проверьте, что восстановленный ключ относится к запрошенным полномочиям и имеет достаточный вес, чтобы подписывать в одиночку.
- Проверьте, что
state— тот, который вы выдали. Каждое сообщение принимайте один раз.
В этом примере используется dhive (https://www.npmjs.com/package/@hiveio/dhive):
import { Client, Signature, cryptoUtils } from '@hiveio/dhive';
const hive = new Client(['https://api.hive.blog']);
// message and authority: what you asked for, from your own records.
// signature and username: from the callback.
export async function verifySignBuffer({ message, authority, signature, username }) {
let recovered;
try {
const hash = cryptoUtils.sha256(message); // sha256 over the UTF-8 bytes
recovered = Signature.fromString(signature).recover(hash).toString();
} catch {
return false; // not a valid signature
}
const [account] = await hive.database.getAccounts([username]);
if (!account) return false;
const auth = account[authority]; // 'posting' or 'active'
return auth.key_auths.some(
([key, weight]) => key === recovered && weight >= auth.weight_threshold,
);
}
Та же проверка подходит для подписи из requestSignBuffer в Hive Keychain. Сравнивайте с ключом, который вы восстановили: public_key на адресе возврата — лишь подсказка.
Сообщения, которые Hivesigner не подписывает
Сообщение, которое является объектом JSON с ключом signed_message, имеет вид токена Hivesigner. Подписав его, вы дали бы запрашивающему доступ к аккаунту человека. Hivesigner никогда не подписывает такое сообщение. Он говорит человеку «Это сообщение является токеном Hivesigner. Подписав его, вы дадите сайту доступ к своему аккаунту, поэтому подписать его нельзя.»
Используйте обычный текст или JSON без ключа signed_message. Скажите, для чего нужна подпись, и добавьте значение, которое создаёте один раз, например:
Confirm your account for YOUR_APP
Account: USERNAME
Nonce: NONCE
Инструмент подписи сообщения
Люди могут и сами подписать сообщение на https://hivesigner.com/signmessage (Подписать сообщение) и проверить его на https://hivesigner.com/verifymessage (Проверить сообщение). Смотрите Подпишите сообщение сами.
Этот инструмент подписывает не так, как /sign-buffer. Он подписывает тело токена Hivesigner, где есть сообщение, аккаунт и время. Результат он выдаёт как Токен проверки. Такой токен проверяйте на странице Проверить сообщение или так, как описано в Проверьте сами, а не кодом выше.