Cómo obtener la dirección de la clave privada en Java

Yo uso generar una clave privada en código JavaHashUtil.sha3("cow".getBytes())

Escribir en un nuevo archivo de clave privada:

c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4

Luego, uso geth account import, obtuve una dirección ["0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826"]en geth.

Pero cuando trato de obtener una dirección pública en Java, muestra una dirección diferente:

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

El resultado esaddress : 8e54de809503da0a87309f8d5e98f77551ddd7f5

Esperaba que se mostrara la dirección cd2a3d9f938e13cd947ec05abc7fe734df8dd826, ¿utilicé un código incorrecto?

También aprendí ECKeyTest.java en EthereumJ, hay pruebas unitarias que primero obtienen la clave pública de la clave privada y luego obtienen la dirección de la clave pública. Pero en mi caso, el resultado sigue siendo 8e54de809503da0a87309f8d5e98f77551ddd7f5.

Olvidé mencionar que en este código, byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());y Hex.encode(senderPrivKey) es igual a "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"

Respuestas (1)

Resumen

En teoría, el código de la pregunta no debería ejecutarse, ya que la clave privada está en formato hexadecimal y la llamada a new BigInteger(senderPrivKey)para analizar la cadena hexadecimal sin 16especificar la raíz daría como resultado una excepción.

Cuando el código se ajusta para usar new BigInteger(senderPrivKey, 16)especificando la raíz base 16, la clave pública se genera como se esperaba.



Los detalles

Aquí hay un ejemplo de trabajo. Guárdelo como TestKey.java, compílelo y ejecútelo.

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

Y la salida al ejecutarlo:

Private key: c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4
Public key: cd2a3d9f938e13cd947ec05abc7fe734df8dd826

He usado la siguiente dependencia maven:

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

No sé cómo se ejecutó su código, porque cuando cambio la siguiente línea en el código fuente anterior para que coincida con su código, el BigInteger(...)constructor espera analizar un número de base 10 en lugar de un número de base 16:

        BigInteger pk = new BigInteger(senderPrivKey);

Y obtengo la siguiente excepción:

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)
Gracias, funciona como un encanto! Agrego un código en el comentario de la pregunta, que en mi código byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());, senderPrivKey no es una cadena, y Hex.encode(senderPrivKey)es"c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"
¿La versión actualizada cambió algo? ¡No puedo generar la dirección!