Как получить адрес из закрытого ключа в Java

Я использую генерировать закрытый ключ в коде JavaHashUtil.sha3("cow".getBytes())

Запишите в новый файл закрытого ключа:

c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4

Затем я использую geth account import, я получил адрес ["0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826"]в geth.

Но когда я пытаюсь получить публичный адрес в Java, он показывает другой адрес:

BigInteger pk = new BigInteger(senderPrivKey);
ECKey key = ECKey.fromPrivate(pk);
System.out.println("address\t: " + Hex.toHexString(key.getAddress()) );

Результатaddress : 8e54de809503da0a87309f8d5e98f77551ddd7f5

Я ожидал, что адрес покажет cd2a3d9f938e13cd947ec05abc7fe734df8dd826, я использовал неправильный код?

Я также изучил ECKeyTest.java в EthereumJ, есть модульные тесты, которые сначала получают открытый ключ из закрытого ключа, а затем получают адрес из открытого ключа. Но в моем случае результат все же есть 8e54de809503da0a87309f8d5e98f77551ddd7f5.

Я забыл упомянуть, что в этом коде , byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());и Hex.encode(senderPrivKey) равно "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"

Ответы (1)

Резюме

Теоретически код в вопросе не должен запускаться, так как закрытый ключ имеет шестнадцатеричный формат, и вызов new BigInteger(senderPrivKey)для анализа шестнадцатеричной строки без 16указанной системы счисления приведет к возникновению исключения.

Когда код корректируется для использования new BigInteger(senderPrivKey, 16)с основанием 16, открытый ключ генерируется, как и ожидалось.



Детали

Вот рабочий пример. Сохраните его как TestKey.java, скомпилируйте и запустите.

import java.math.BigInteger;

import org.ethereum.crypto.ECKey;
import org.spongycastle.util.encoders.Hex;

public class TestKey {

    public static void main(String[] args) {
        String senderPrivKey = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";

        BigInteger pk = new BigInteger(senderPrivKey, 16);
        System.out.println("Private key: " + pk.toString(16));

        ECKey key = ECKey.fromPrivate(pk);
        System.out.println("Public key: " + Hex.toHexString(key.getAddress()));
    }
}

И вывод при его запуске:

Private key: c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4
Public key: cd2a3d9f938e13cd947ec05abc7fe734df8dd826

Я использовал следующую зависимость maven:

    <dependency>
        <groupId>org.ethereum</groupId>
        <artifactId>ethereumj-core</artifactId>
        <version>1.1.0-RELEASE</version>
        <!--  <type>zip</type>  -->
    </dependency>

Я не знаю, как работал ваш код, потому что, когда я изменяю следующую строку в исходном коде выше, чтобы она соответствовала вашему коду, BigInteger(...)конструктор ожидает, что он будет анализировать число с основанием 10, а не число с основанием 16:

        BigInteger pk = new BigInteger(senderPrivKey);

И я получаю следующее исключение:

Exception in thread "main" java.lang.NumberFormatException: For input string: "c"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.math.BigInteger.<init>(BigInteger.java:461)
    at java.math.BigInteger.<init>(BigInteger.java:597)
    at TestKey.main(TestKey.java:14)
Спасибо, это работает как шарм! Я добавляю код в комментарий к вопросу, что в моем коде byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());senderPrivKey не является строкой, Hex.encode(senderPrivKey)а"c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"
В обновленной версии что-то изменилось? Я не могу сгенерировать адрес!