संदेश पर हस्ताक्षर

आपका ऐप किसी उपयोगकर्ता से कह सकता है कि वह अपनी पोस्टिंग या सक्रिय कुंजी से कोई पाठ संदेश साइन करे। हस्ताक्षर साबित करता है कि खाता उसी के नियंत्रण में है। कुछ भी प्रसारित नहीं होता: संदेश कभी ब्लॉकचेन तक नहीं पहुँचता। Hivesigner ठीक वैसे ही साइन करता है जैसे Hive Keychain का requestSignBuffer, इसलिए जो सर्वर कोड 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 भी पढ़ा जाता है।

URL को 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 खाता न हो, या कॉलबैक उस ऐप पर पंजीकृत न हो। उपयोगकर्ता को «हस्ताक्षर का यह अनुरोध इस्तेमाल नहीं किया जा सकता: इसके लिए एक संदेश, एक पोस्टिंग या सक्रिय कुंजी और ऐप के लिए पंजीकृत एक सुरक्षित रीडायरेक्ट URL चाहिए। साइट पर वापस जाकर फिर से कोशिश करें।» और इस समस्या की रिपोर्ट करें बटन दिखता है।

उपयोगकर्ता क्या देखता है

  • एक शीर्षक जिसमें आपके ऐप का नाम (या कॉलबैक का होस्ट) और «आपको 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 उसकी खाता सूची खोल देता है। आपके कॉलबैक को कुछ नहीं मिलता।

चेतावनी: कोई भी आपका कॉलबैक मनगढ़ंत मानों के साथ खोल सकता है। जब तक आपका सर्वर हस्ताक्षर न जाँच ले, हर पैरामीटर को सिर्फ़ एक दावा मानें।

हस्ताक्षर सत्यापित करें

हस्ताक्षर अपने सर्वर पर जाँचें:

  1. जो संदेश आपने माँगा था उसे उसके state के साथ अपने सर्वर पर रखें। ब्राउज़र से लौटी किसी नक़ल पर भरोसा न करें।
  2. संदेश का हैश निकालें: उसके UTF-8 बाइट पर sha256।
  3. हस्ताक्षर और उसी हैश से सार्वजनिक कुंजी निकालें।
  4. Hive से खाता लोड करें। जाँचें कि निकाली हुई कुंजी उसी अधिकार की है जो आपने माँगा था, और अकेले साइन करने लायक भार रखती है।
  5. जाँचें कि 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,
  );
}

यही जाँच Hive Keychain के requestSignBuffer से आए हस्ताक्षर पर भी चलती है। उसी कुंजी से मिलाएँ जो आपने निकाली है: कॉलबैक का public_key सिर्फ़ एक संकेत है।

जिन संदेशों को Hivesigner साइन नहीं करता

जो संदेश signed_message कुंजी वाला JSON ऑब्जेक्ट हो, उसका रूप 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 टोकन की बॉडी साइन करता है जिसमें संदेश, खाता और समय होता है। नतीजा वह सत्यापन टोकन के रूप में साझा करता है। ऐसे टोकन को संदेश सत्यापित करें पन्ने पर जाँचें या जैसा खुद जाँचें में बताया गया है, ऊपर वाले कोड से नहीं।