Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
atticlab
6 лет назад

Как Защитить Сообщения в EOS

Оригинал: https://medium.com/coinmonks/how-to-secure-messages-on-eos-ebb869a459ea
Права на текст статьи принадлежат автору

Блокчейн - это распределенный реестр, и каждый блок данных доступен для всеобщего обозрения. Возможно, вам интересно, что делать, если вы хотите зашифровать сообщения в блокчейне, а именно, в EOS?_

Как Обеспечивается Безопасность Сообщений в Блокчейне

Мы можем использовать NuCypher. NuCypher помогает разработчикам dApp хранить, совместно использовать и управлять личными данными в общедоступных блокчейнах с децентрализованным повторным шифрованием прокси в качестве сервиса.

Вот как это работает.

У Алисы есть конфиденциальные данные, на которые она хочет иметь возможность делегировать доступ.
Алиса шифрует свои данные с помощью собственного открытого ключа и сохраняет их в облаке или децентрализованном хранилище.
Алиса делегирует доступ Бобу. Данные переустановлены на ключ Боба в хранилище.
Боб загружает данные и расшифровывает их своим личным ключом.

Защита сообщения в EOS

Мы начнем со сценария, в котором у Алисы и Боба есть доступ к закрытому ключу, и Алиса хочет отправить конфиденциальные данные Бобу, а также использовать pyUmbral , который является эталонной реализацией NuCypher для Umbral (split-key threshold proxy re-encryption).

Давайте сначала построим смарт-контракт поочередности сообщений в EOS.

Он создает одну таблицу, называемую сообщениями, которая содержит uint64_t msg_id, account_name from, account_name to, строковый зашифрованный текст и строковую капсулу. msg_id является первичным ключом.

Он обеспечивает два действия: sendmsg и deletemsg . sendmsg требует account_name from и to, msg_id, зашифрованный текст и капсулу. Зашифрованный текст - это зашифрованное сообщение, а капсула - это концепция в Umbral, которая генерируется с использованием pyUmbral. deletemsg в основном получает msg_id, проверяет данное to account_name, а затем удаляет запись.

class queue: public eosio::contract {

public:
    using contract::contract;

    //@abi action
    void sendmsg( account_name from, account_name to, uint64_t msg_id, const std::string & ciphertext, const std::string & capsule) {

        require_auth( from );
        messages_index messages( _self, _self );
        auto itr = messages.find(msg_id);
        if (itr != messages.end()) {
            std::string error = "msg_id already exists: " + 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 = ciphertext;
            msg.capsule = capsule;
        });

    }

    // @abi action
    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 does not exist: " + std::to_string(msg_id);
            eosio_assert(false, error.c_str());
        }
        
        if ( itr->to != to ) {
            std::string error = "Receipient not correct: " + eosio::name{itr->to}.to_string();
            eosio_assert( false, error.c_str());
        }
      
        messages.erase(itr);
     }

private:
    //@abi table messages i64
    struct messages {
        uint64_t msg_id;
        account_name from;
        account_name to;
        std::string ciphertext;
        std::string capsule;

        uint64_t primary_key() const { return msg_id;}

    };
    
    typedef eosio::multi_index<N(messages), messages> messages_index;

};

EOSIO_ABI( queue, (sendmsg)(deletemsg) )

Скомпилируйте его:

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

Создайте учетную запись, чтобы загрузить смарт-контракт:

cleos create account eosio queue EOS5aEqZf22dfThTR8GGMnD8oFvsyzssQnhawNwPzfPv4fwDWhf7H
executed transaction: a767af2c66857... 200 bytes 3309 us
eosio <= eosio::newaccount {"creator":"eosio","name":"queue","owner":{"threshold":1,"keys":[{"key":"EOS5aEqZf22dfThTR8GGMnD8oFv…

$ cleos set contract queue ../queue
Reading WAST/WASM from ../queue/queue.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 38e94741c... 13824 bytes 9561 us
eosio <= eosio::setcode {"account":"queue","vmtype":0,"vmversion":0,"code":"00617ee7e...
eosio <= eosio::setabi {"account":"queue","abi":"0e656f73696f3a3a6162692f9640675...

Создайте тестовые учетные записи alice и bob:

$ cleos create account eosio alice EOS6NU3XEvosgRVEbhrBHrkbYVteW7DDVewhjo9jgiYoSqUZamnZe
executed transaction: f0c42065f6d9fc... 200 bytes 243 us
eosio <= eosio::newaccount {"creator":"eosio","name":"alice","owner":{"threshold":1,"keys":[{"key":"EOS6NU3XEvosgRVEbhrBHrkbYVt...

$ cleos create account eosio bob EOS7cX17CZ8V7yFobaVejAN7sMG39iiC5BmFk7b1NB1NNYcrEu1Go
executed transaction: 51d45916fa252e... 200 bytes 194 us
eosio <= eosio::newaccount {"creator":"eosio","name":"bob","owner":{"threshold":1,"keys":[{"key":"EOS7cX17CZ8V7yFobaVejAN7sMG39...

Давайте перейдем к созданию клиента для шифрования / дешифрования сообщения и взаимодействия со смарт-контрактом.

Создайте личный ключ и запишите в файл.

from umbral import config, keys

config.set_default_curve(SECP256K1)
private_key = keys.UmbralPrivateKey.gen_key()
f = open('priv.key', 'wb')
f.write(private_key.to_bytes())
f.close()

Создайте парсер

def create_parser():
parser = argparse.ArgumentParser(description = 'messenger')
parser.add_argument('--private-key-file', type = str, dest = 'private_key_file', required = False, help = 'Path to the private key file.')
parser.add_argument('--send-msg-id', type = str, dest = 'send_msg_id', required = False, help = 'Send a message, msg_id')
parser.add_argument('--send-msg-from', type = str, dest = 'send_msg_from', required = False, help = 'Send a message, from which EOS account')
parser.add_argument('--send-msg-to', type = str, dest = 'send_msg_to', required = False, help = 'Send a message, to which EOS account')
parser.add_argument('--send-msg', type = str, dest = 'send_msg', required = False, help = 'Message to be sent')
parser.add_argument('--read-msg-to', type = str, dest = 'read_msg_to', required = False, help = 'Read a message, to which EOS account')
return parser

parser = create_parser()
args = parser.parse_args(argv)

Читайте из файла privkey.

def read_privkey_file(privkey_file):
if os.path.exists(privkey_file):
with open(privkey_file, 'rb') as f:
try:
privkey = f.read()
except Exception as e:
print("Cannot read: {}".format(e))
sys.exit(1)
f.close()
return privkey

else:
    print('Cannot find file: {}'.format(privkey_file))
    sys.exit(1)

** Зашифруйте сообщение и отправьте его.**

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()

plaintext = msg.encode()
ciphertext, capsule = pre.encrypt(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])

Читайте из messages таблицы, если to соответствует read_msg_to, расшифруйте сообщение и затем удалите его.

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"}'
response = requests.request("POST", DEFAULT_URL, data=payload)   

found = False
for msg in response.json()['rows']:
    if msg['to'] == read_msg_to:
        ciphertext = msg['ciphertext']
        capsule = msg['capsule']
        msg_id = msg['msg_id']
        found = True
        break

if found:        
    capule = pre.Capsule.from_bytes(bytes.fromhex(capsule), privkey.params)
    cleartext = pre.decrypt(
                      ciphertext = bytes.fromhex(ciphertext),
                      capsule = capule,
                      decrypting_key = privkey)
    print('Cleartext: {}'.format(cleartext))

    print('Deleting 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])

Значения по умолчанию.

DEFAULT_ACCOUNT = 'queue'

DEFAULT_TABLE = 'messages'

DEFAULT_URL= "http://127.0.0.1:8888/v1/chain/get_table_rows"

Давайте завернем их и проверим!

$ python3 messenger.py --private-key-file priv.key --send-msg-id 1 --send-msg-from alice --send-msg-to bob --send-msg hello,bob

executed transaction: dfe17144e105c54d192... 392 bytes 648 us
queue <= queue::sendmsg {"from":"alice","to":"bob","msg_id":1,"ciphertext":"8c53a656c9...

Проверьте messages таблицу.

$ cleos get table queue queue messages
{
"rows": [{
"msg_id": 1,
"from": "alice",
"to": "bob",
"ciphertext": "8c8aa24196152b53da35d9fbf9e3c4d8e10f6b7153a656c9921cb440cc69a782c2ba0c2cf2",
"capsule": "028c4e8279c0919bdec4ea98b4251f15a74868d2ea7554ab796230af8f88e62cd9031c07e90c6183152e140c43a370f2c12526b6d62269f8673a35e6a19fc6ff78ac2f3a28dbed868858ec71228644f277c8ecfb691aa41dab863072e6f39c55d294"
}
],
"more": false
}

Зашифрованное сообщение есть. Тогда давайте прочитаем.

$ python3 messenger.py --private-key-file priv.key --read-msg-to bob

Cleartext: b'hello,bob'
Deleting msg_id: 1

executed transaction: 6cdad7694f3fe6c8...112 bytes 566 us
queue <= queue::deletemsg {"to":"bob","msg_id":1}

Проверьте messages таблицу, сообщение исчезло.

$ cleos get table queue queue messages
{
"rows": [],
"more": false
}

Таким образом, мы изучили, как защищать сообщения в EOS. В дальнейшем, мы можем поработать над сценарием, где у Алисы и Боба есть свои собственные ключи, или отправлять нескольким пользователям.
Примечание: в строках, начинающихся с eosio, вставлять в начале #

Follow us!

Website: https://atticlab.net/eos/

Twitter: https://twitter.com/atticlab_it

Facebook: https://www.facebook.com/atticlab/

Reddit: https://www.reddit.com/r/atticlabeosb/

Steemit: https://steemit.com/eos/@attic-lab

Medium: https://medium.com/eosatticlab

Golos: https://golos.io/@atticlab

Telegram Chat: https://t.me/atticlabeosb

Telegram channel: https://t.me/eos_atticlab

0
0.102 GOLOS
На Golos с August 2018
Комментарии (0)
Сортировать по:
Сначала старые