So sichern Sie Nachrichten unter EOS

Eine Blockchain ist ein verteiltes Hauptbuch und jeder Datenblock ist öffentlich zugänglich. Sie fragen sich vielleicht, was passiert, wenn ich Nachrichten in Blockchain verschlüsseln möchte, insbesondere unter EOS?

So sichern Sie Nachrichten in einer Blockchain

Wir können NuCypher einbinden. NuCypher unterstützt dApp-Entwickler beim Speichern, Freigeben und Verwalten privater Daten in öffentlichen Blockchains mit dezentraler Proxy-Neuverschlüsselung als Service.

So funktioniert es.

  1. Alice hat vertrauliche Daten, auf die sie den Zugriff delegieren möchte.
  2. Alice verschlüsselt ihre Daten mit ihrem eigenen öffentlichen Schlüssel und speichert sie in der Cloud oder im dezentralen Speicher.
  3. Alice delegiert den Zugriff auf Bob. Die Daten werden auf Bobs Schlüssel im Speicher umgeschlüsselt.
  4. Bob lädt die Daten herunter und entschlüsselt sie mit seinem privaten Schlüssel.

Sichern einer Nachricht auf EOS

Wir beginnen mit dem Szenario, in dem Alice und Bob beide Zugriff auf den privaten Schlüssel haben und Alice vertrauliche Daten an Bob senden und pyUmbral nutzen möchte, die NuCyphers Referenzimplementierung von Umbral (Proxy-Neuverschlüsselung mit geteiltem Schlüssel).

Erstellen wir zunächst einen intelligenten Vertrag für die Nachrichtenwarteschlange in EOS.

Es erstellt eine Tabelle namens messages, die uint64_t msg_id, account_name from, account_name to, string ciphertext und string capsule enthält. msg_id ist der Primärschlüssel.

Es bietet zwei Aktionen: sendmsg und deletemsg. sendmsg benötigt account_name von und bis, msg_id, chiffretext und kapsel. Chiffretext ist die verschlüsselte Nachricht und Kapsel ist das Konzept in Umbral, das mit pyUmbral generiert wird. deletemsg nimmt im Grunde genommen eine msg_id, überprüft den angegebenen account_name und löscht dann den Datensatz.

Klassenwarteschlange: public eosio :: contract {
    Öffentlichkeit:
        using contract :: contract;
        // @ abi Aktion
        void sendmsg (kontoname von, kontoname bis, uint64_t msg_id, const std :: string & chiffretext, const std :: string & kapsel) {
            require_auth (from);
            messages_index messages (_self, _self);
            auto itr = messages.find (msg_id);
            if (itr! = messages.end ()) {
                std :: string error = "msg_id existiert bereits:" + std :: to_string (msg_id);
                eosio_assert (false, error.c_str ());
            }
            messages.emplace (from, [&] (auto & msg) {
                msg.msg_id = msg_id;
                msg.from = from;
                msg.to = to;
                msg.ciphertext = chiffretext;
                msg.capsule = capsule;
            });
        }
        // @abi Aktion
        void deletemsg (account_name to, uint64_t msg_id) {
            require_auth (to);
            messages_index messages (_self, _self);
            auto itr = messages.find (msg_id);
            if (itr == messages.end ()) {
                std :: string error = "msg_id existiert nicht:" + std :: to_string (msg_id);
                eosio_assert (false, error.c_str ());
            }
            
            if (itr-> to! = to) {
                std :: string error = "Empfänger nicht korrekt:" + eosio :: name {itr-> to} .to_string ();
                eosio_assert (false, error.c_str ());
            }
          
            messages.erase (itr);
         }
    Privatgelände:
        // @ abi table messages i64
        struct messages {
            uint64_t msg_id;
            kontoname von;
            account_name to;
            std :: string chiffretext;
            std :: string capsule;
            uint64_t primary_key () const {return msg_id;}
        };
        
        typedef eosio :: multi_index  nachrichten_index;
};
EOSIO_ABI (Warteschlange, (sendmsg) (deletemsg))

Kompiliere es:

eosiocpp -o queue.wast queue.cpp
eosiocpp -g queue.abi queue.cpp

Erstellen Sie ein Konto, um den Smart-Vertrag hochzuladen:

$ cleos Konto erstellen eosio Warteschlange EOS5aEqZf22dfThTR8GGMnD8oFvsyzssQnhawNwPzfPv4fwDWhf7H
ausgeführte Transaktion: a767af2c66857 ... 200 Bytes 3309 us
# eosio <= eosio :: newaccount {"Ersteller": "eosio", "Name": "Warteschlange", "Eigentümer": {"Schwelle": 1, "Schlüssel": [{"Schlüssel": "EOS5aEqZf22dfThTR8GGMnD8oFv .. .
$ cleos Vertragswarteschlange setzen ../queue
Lesen von WAST / WASM aus ../ queue / queue.wasm ...
Mit bereits montiertem WASM ...
Veröffentlichungsvertrag ...
ausgeführte Transaktion: 38e94741c ... 13824 Bytes 9561 us
# eosio <= eosio :: setcode {"account": "queue", "vmtype": 0, "vmversion": 0, "code": "00617ee7e ...
# eosio <= eosio :: setabi {"account": "queue", "abi": "0e656f73696f3a3a6162692f9640675 ...

Erstellen Sie Testaccounts alice und bob:

$ cleos Konto erstellen eosio alice EOS6NU3XEvosgRVEbhrBHrkbYVteW7DDVewhjo9jgiYoSqUZamnZe
ausgeführte Transaktion: f0c42065f6d9fc ... 200 Bytes 243 us
# eosio <= eosio :: newaccount {"Ersteller": "eosio", "Name": "Alice", "Besitzer": {"Schwelle": 1, "Schlüssel": [{"Schlüssel": "EOS6NU3XEvosgRVEbhrBHrkbYVt .. .
$ cleos Konto erstellen eosio bob EOS7cX17CZ8V7yFobaVejAN7sMG39iiC5BmFk7b1NB1NNYcrEu1Go
ausgeführte Transaktion: 51d45916fa252e ... 200 Bytes 194 us
# eosio <= eosio :: newaccount {"Ersteller": "eosio", "Name": "Bob", "Eigentümer": {"Schwelle": 1, "Schlüssel": [{"Schlüssel": "EOS7cX17CZ8V7yFobaVejAN7sMG39 .. .

Lassen Sie uns einen Client erstellen, um eine Nachricht zu verschlüsseln / entschlüsseln und mit dem Smart-Vertrag zu interagieren.

  1. Generieren Sie einen privaten Schlüssel und schreiben Sie in eine Datei.
von Umbral Import Config, Schlüssel
config.set_default_curve (SECP256K1)
private_key = keys.UmbralPrivateKey.gen_key ()
f = open ('priv.key', 'wb')
f.write (private_key.to_bytes ())
f.close ()

2. Konstruieren Sie einen Parser

def create_parser ():
    parser = argparse.ArgumentParser (description = 'messenger')
    parser.add_argument ('- private-key-file', type = str, dest = 'private_key_file', required = False, help = 'Pfad zur privaten Schlüsseldatei.')
    parser.add_argument ('- send-msg-id', type = str, dest = 'send_msg_id', required = False, help = 'Nachricht senden, msg_id')
    parser.add_argument ('- send-msg-from', type = str, dest = 'send_msg_from', required = False, help = 'Nachricht senden, von welchem ​​EOS-Konto aus')
    parser.add_argument ('- send-msg-to', type = str, dest = 'send_msg_to', required = False, help = 'Nachricht senden, an welches EOS-Konto')
    parser.add_argument ('- send-msg', type = str, dest = 'send_msg', required = False, help = 'Zu sendende Nachricht')
    parser.add_argument ('- read-msg-to', type = str, dest = 'read_msg_to', required = False, help = 'Nachricht lesen, für welches EOS-Konto')
    Parser zurückgeben
parser = create_parser ()
args = parser.parse_args (argv)

3. Lesen Sie aus der privkey-Datei.

def read_privkey_file (privkey_file):
    if os.path.exists (privkey_file):
        mit open (privkey_file, 'rb') als f:
            Versuchen:
                privkey = f.read ()
            außer Ausnahme als e:
                print ("Kann nicht lesen: {}". format (e))
                sys.exit (1)
            f.close ()
            privkey zurückgeben
    sonst:
        print ('Datei kann nicht gefunden werden: {}'. format (privkey_file))
        sys.exit (1)

3. Verschlüsseln Sie eine Nachricht und senden Sie sie.

def send_msg (private_key_file, msg, send_msg_from, send_msg_to, send_msg_id):
    privkey_bytes = read_privkey_file (private_key_file)
    privkey = keys.UmbralPrivateKey.from_bytes (privkey_bytes)
    pubkey = privkey.get_pubkey ()
    Klartext = msg.encode ()
    chiffretext, kapsel = vorverschlüsseln (pubkey, plaintext)
    data = '{"from": "+ send_msg_from +'", "to": "+ send_msg_to + '", "msg_id": "+ send_msg_id +'", "ciphertext": "'+ ciphertext.hex () + '"," capsule ":"' + capsule.to_bytes (). hex () + '"}'
    subprocess.call (['cleos', 'push', 'action', DEFAULT_ACCOUNT, 'sendmsg', data, '-p', send_msg_from])

3. Lesen Sie aus der Nachrichtentabelle, ob read_msg_to übereinstimmt, entschlüsseln Sie eine Nachricht und löschen Sie sie anschließend.

def read_and_delete_msg (private_key_file, read_msg_to):
    privkey_bytes = read_privkey_file (private_key_file)
    privkey = keys.UmbralPrivateKey.from_bytes (privkey_bytes)
    
    payload = '{"scope": "' + DEFAULT_ACCOUNT + '", "code": "+ DEFAULT_ACCOUNT +'", "table": "+ DEFAULT_TABLE + '", "json": "true"}'
    Antwort = Anfragen.Anfrage ("POST", DEFAULT_URL, Daten = Nutzdaten)
    
    gefunden = falsch
    für msg in response.json () ['rows']:
        if msg ['to'] == read_msg_to:
            ciphertext = msg ['ciphertext']
            kapsel = msg ['kapsel']
            msg_id = msg ['msg_id']
            found = True
            brechen
    wenn gefunden:
        capule = pre.Capsule.from_bytes (bytes.fromhex (kapsel), privkey.params)
        Klartext = pre.decrypt (
                          chiffretext = bytes.fromhex (chiffretext),
                          kapsel = kapsel,
                          decrypting_key = privkey)
        Drucken ('Klartext: {}'. Format (Klartext))
        print ('Löschen von msg_id: {}'. format (msg_id))
        data = '{"to": "' + read_msg_to + '", "msg_id": "' + str (msg_id) + '"}'
        subprocess.call (['cleos', 'push', 'action', DEFAULT_ACCOUNT, 'deletemsg', data, '-p', read_msg_to])

4. Standardwerte.

DEFAULT_ACCOUNT = 'Warteschlange'
DEFAULT_TABLE = 'messages'
DEFAULT_URL = "http://127.0.0.1:8888/v1/chain/get_table_rows"

Packen wir sie ein und testen sie!

$ python3 messenger.py --private-key-file priv.key --send-msg-id 1 --send-msg-from alice --send-msg-to bob --send-msg hallo, bob
ausgeführte Transaktion: dfe17144e105c54d192 ... 392 Bytes 648 us
# queue <= queue :: sendmsg {"from": "alice", "to": "bob", "msg_id": 1, "ciphertext": "8c53a656c9 ...

Überprüfen Sie die Nachrichtentabelle.

$ cleos ruft Warteschlangenachrichten für Tabellen ab
{
  "Reihen": [{
      "msg_id": 1,
      "from": "alice",
      "to": "bob",
      Geheimtext: 8c8aa24196152b53da35d9fbf9e3c4d8e10f6b7153a656c9921cb440cc69a782c2ba0c2cf2,
      "Kapsel": 028c4e8279c0919bdec4ea98b4251f15a74868d2ea7554ab796230af8f88e62cd9031c07e90c6183152e140c43a370f2c12526b6d62269f8673a35e6a6b6c6b6cd19d19d6
    }
  ],
  "more": false
}

Die verschlüsselte Nachricht ist da. Dann lass es uns lesen.

$ python3 messenger.py --private-key-file priv.key --read-msg-to bob
Klartext: b'hello, bob '
Löschen von msg_id: 1
ausgeführte Transaktion: 6cdad7694f3fe6c8 ... 112 Bytes 566 us
# queue <= queue :: deletemsg {"to": "bob", "msg_id": 1}

Überprüfen Sie die Nachrichtentabelle, die Nachricht ist weg.

$ cleos ruft Warteschlangenachrichten für Tabellen ab
{
  "Reihen": [],
  "more": false
}

Daher haben wir untersucht, wie Nachrichten unter EOS gesichert werden können. In Zukunft können wir an einem Szenario arbeiten, in dem Alice und Bob ihre eigenen Schlüssel haben oder an mehrere Benutzer senden.

Unsere sozialen Netzwerke

Webseite
Twitter
Youtube
Meetup
Steem