Расположение открытых и закрытых ключей учетной записи Ethereum

Я хочу узнать подробности о генерации и обработке ключей в Parity. Все перечисленные вопросы связаны между собой, поэтому я поместил их все в этот пост с вопросами.

Когда в Parity создается новая учетная запись Ethereum, создается новый файл с расширением .../ethcore/<node-name>/keys/<chain-name>. Например, содержимое такого файла:

{
    "id":"eca798d8-8e68-a096-a35f-174133f86e43",
    "version":3,
    "crypto":
    {
        "cipher":"aes-128-ctr",
        "cipherparams": { "iv":"45092c0a2032250e66a9d0bd2a33acaa" },
        "ciphertext":"0385fd52dfc528713d7b0b72073b992b93aa78f32b0576848a9de69d6e836c3d",
        "kdf":"pbkdf2",
        "kdfparams":
        {
            "c":10240,
            "dklen":32,
            "prf":"hmac-sha256",
            "salt":"e04e80b6174ca47c86e9174fd952949e53c900852d5c3cb62b863c5241e54f28"
        },
        "mac":"178d2c012e1970b853e1551fa9bb0a51b86955cc4ed8db53a9b60cbbdbca8c7b"
    },
    "address":"00faf16e4909296f5cca76e1ccd7cd811fba93d0",
    "name":"User-007",
    "meta":"{}"
}

Похоже, что KDF - это PBKDF2, т.е. KDF на основе пароля. Я предполагаю, что пароль учетной записи используется для получения ключей, и параметры для этого приведены в файлах "kdfparams".

Итак, я ищу ответы на следующие вопросы:

  1. Является ли закрытый ключ полученным с использованием этого KDF и заданных значений параметров по требованию всякий раз, когда предоставляется пароль?
  2. Что такое открытый ключ или как он генерируется? Пароль для этого не нужен.
  3. Что такое обычный текст, который "ciphertext"является зашифрованным?
  4. Этот файл создается и сохраняется на узле Parity. Разве это не означает, что закрытый ключ не находится полностью и исключительно в руках владельца учетной записи?

Спасибо, что пролили свет на этот вопрос.

github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition может иметь некоторые ответы
Не могли бы вы пояснить свой 4-й вопрос? Почему оператор узла не имеет полного контроля над ключами?
Re: Q4: Возможно, я не правильно понял это раньше, но после публикации мне пришло в голову, что человек, создающий учетную запись, также является владельцем узла, на котором personal.newAccountFromPhraseвызывается операция создания учетной записи (или любая другая). Это означает, что нужно запустить клиент Parity (или любого другого Ethereum) на узле, которым он управляет, и вызвать на нем операцию создания учетной записи. Это правильно? т.е. я не должен создавать учетную запись, вызывая API удаленного узла, который не находится под моим контролем?
@AjoyBhatia да. Удаленный (RPC) узел, вероятно personal, все равно не разрешит API, если только он не укажет это с помощью --rpcapi. Вы должны сгенерировать файл закрытого ключа только на своем компьютере. Его также можно расшифровать и получить необработанный закрытый ключ, см . здесь .
@eth - Спасибо за ссылку на вики. Это хорошая информация. Теперь осталось только одно — где открытый ключ? ИЛИ Как алгоритм проверки подписи узнает, что такое открытый ключ данного адреса, чтобы быть в состоянии проверить, было ли данное сообщение подписано закрытым ключом, соответствующим этому адресу? Я поищу эту информацию и задам новый вопрос, если не найду.
У Тайвано есть ответы, которые могут помочь, на ethereum.stackexchange.com/questions/13778/… и ethereum.stackexchange.com/questions/3542/… Не стесняйтесь написать исчерпывающий ответ на свой вопрос, чтобы собрать вещи воедино.

Ответы (1)

Некоторые ссылки в комментариях помогли мне получить ответы на мои вопросы. Я собрал всю эту информацию в сочетании с моими собственными (недавно полученными) знаниями в области криптографии на курсе Coursera Cryptography-I (для ответа на вопрос номер 3).

А1. Закрытый ключ никогда (и никогда не должен) сохраняться на диске в незашифрованном виде. Он генерируется из информации в файле хранилища ключей, когда пользователь вводит пароль.

А2. Открытый ключ может быть сгенерирован из закрытого ключа. Однако другим сторонам (у которых нет закрытого ключа) необходимо проверить подписи этой учетной записи. Эти стороны получат его из подписи, как описано здесь: Получить открытый ключ любой учетной записи ethereum Затем адрес подписавшего — это последние 20 байт хэша Keccak-256 открытого ключа. Предположительно, это должно совпадать с from:адресом транзакции.

А3. Вот (несколько длинный) ответ о структуре и значении представления JSON закрытого ключа:

Я получил много этой информации со страницы вики: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition и добавил кое-что от себя, чтобы сделать ее более полной.

Вся информация для расшифровки закрытого ключа находится в cryptoэлементе. Элемент cipherидентифицирует схему симметричного шифрования, используемую для шифрования закрытого ключа. В данном примере схема представляет aes-128-ctrсобой блочный шифр Advanced Encryption Standard (aes ) с длиной ключа в 128битах в режиме счетчика ( ctr). В сторону: другим режимом работы является цепочка блоков шифрования (CBC) . cipherparamsсодержит значения любых параметров, используемых при шифровании. Для AES-128-CTR имеется только один параметр iv(вектор инициализации). ciphertextявляется зашифрованным закрытым ключом.

Чтобы расшифровать закрытый ключ ciphertext, нам нужны указанные выше значения. Нам также нужен симметричный ключ шифрования, который использовался для шифрования закрытого ключа. Ключ шифрования также не отображается в виде обычного текста. Его необходимо получить с помощью указанной функции вывода ключа ( kdf), используя значения параметров, которые требуются указанному KDF ( kdfparams). KDF в данном примере - pbkdf2KDF на основе пароля. Параметрами для pbkdf2являются пароль (вводится пользователем), псевдослучайная функция хэширования ( prf) (например, это HMAC-SHA256 hmac-sha256), солт-значение ( salt), количество итераций ( c) и полученная длина ключа. (dklen) в байтах. Ключ получается путем объединения значений пароля и соли и применения времени функции хеширования c. Это делается потому, что пароли, выбранные людьми, не обладают достаточной энтропией. Для защиты от этого используется случайное значение соли, а также медленная хэш-функция. (Количество итераций нужно для того, чтобы сделать хэш-функцию медленнее. Это не делает получение ключа более безопасным (как некоторые считают). Это только увеличивает время, чтобы затруднить атаки грубой силы.)

После получения ключа шифрования он проверяется с использованием значения MAC ( mac). Второй блок из 128 бит (16 байт) объединяется со ciphertextзначением. Хэш Keccak-256 результирующего массива байтов должен быть равен macзначению.

Если ключ шифрования проходит проверку, то он используется для расшифровки ciphertext, используя указанную функцию расшифровки cipherсо значениями параметров, указанными в cipherparams. Результатом этой расшифровки является открытый текстовый закрытый ключ.

А4. Позже я понял, что новую учетную запись нужно создавать только на узле, контролируемом им самим. По этой причине personalAPI включен по умолчанию на IPC, но не на RPC, чтобы предотвратить принятие запроса на создание новой учетной записи удаленным узлом.

Много текста о вопросе 3, но на самом деле нет ответа на вопрос. Все, кажется, танцуют вокруг расшифровки ключей. У меня есть файл UTC, у меня есть пароль к UTC: какую команду использовать для расшифровки и отображения закрытого ключа И никаких лекций по безопасности, пожалуйста. Мой ключ, мой кошелек, моя ответственность.
Что ж, это был мой вопрос и, после глубокого изучения, мой ответ. Я не хотел извлекать определенный закрытый ключ из определенного файла UTC. Я хотел понять, что означает содержимое файла UTC . Я даже не знал, какие данные ciphertextдолжны быть зашифрованы. Из Q.1 вы можете видеть, что я предположил, что KDF использует свои параметры и пароль для получения закрытого ключа. Итак, какова цель ciphertext? Какие данные он должен представлять? Информация в моем ответе была именно тем, что я искал, когда задавал эти вопросы. Мой вопрос, мой ответ.
Если это было полезно для вас, это хорошо. Если нет, возможно, вы ищете что-то еще, что вы можете найти где-то еще :-)
Есть простая программа, которая делает именно это. Ссылка на ethereum.stackexchange.com/a/61020
Спасибо, @nix. Это полезно. Этот вопрос касался не только получения закрытого ключа. Я хотел понять каждое поле в этом содержимом файла JSON, как поля связаны друг с другом, зачем они нужны и как они используются и т. д. Возможно, заголовок здесь вводит в заблуждение. Эта простая программа, кажется, была тем, что Мартин Мэй (первый комментатор выше) ожидал найти из-за этого названия.