Ich versuche, einen öffentlichen und privaten Schlüsselsatz aus einer Eingabezeichenfolge in Java zu generieren. (Ja, mir ist bewusst, dass dies eine gefährliche Praxis sein kann) Ich verwende Bitcoin für eine externe Bibliothek.
Ich habe derzeit:
//public key generation from private key
static String getPublicKey(byte[] privKey) {
Address address = new Address(MainNetParams.get(),
Utils.sha256hash160(ECKey.fromPrivate(privKey, false).getPubKey()));
return address.toString();
}
///hash string to generate private key from string
static byte[] sha256(String base) {
try{
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(base.getBytes("UTF-8"));
return hash;
} catch(Exception ex){
throw new RuntimeException(ex);
}
}
//encode private key as string to display
static String privToString(byte[] hash) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
Wenn ich Folgendes ausführe: Seed String: icecreampaintjob
Ich bekomme folgendes:
Öffentlich: 1KdoiXMYFn2qa8uGGiNqfrwFRDu3j2qQNA
Privat: dba1e3e22415c56af772dee422add21b7382ea35f2af77852a8069d02e47ecf4
Mit bitaddress.org zur Kreuzverifizierung bekomme ich:
Privat: 5KV1o7tRK8pNqrPNYyi38nrik9r2Y85sjdgFDttnDiT1uZrQ1fj (MACHT NICHT)
Öffentlich: 1KdoiXMYFn2qa8uGGiNqfrwFRDu3j2qQNA (STIMME ZU)
Was vermisse ich?
Wie bitaddress.org BrainWallet in seiner Anzeige sagt
Private Key (Wallet Import Format):
5KV1o7tRK8pNqrPNYyi38nrik9r2Y85sjdgFDttnDiT1uZrQ1fj
Das Wallet-Importformat ist die übliche base58-Panzerung, die auf den Privatekey-Wert mit „Version“ 0x80 angewendet wird.
Siehe https://en.bitcoin.it/wiki/Wallet_import_format oder ausführlicher https://en.bitcoin.it/wiki/Base58Check_encoding . Dies ist im Grunde ein Duplikat von Gibt es eine Möglichkeit, eine Brain Wallet über die Befehlszeile oder Konsole zu generieren? obwohl das bash + dc anstelle von Java verwendet.
Nicht getestet, aber für mich VersionChecksummedBytes(0x80,bytes).toBase58()
sieht es so aus.
Ich denke, new VersionedChecksummedBytes(0x80, priv).toBase58()
das ist die richtige Idee, aber die Konstruktoren sind geschützt und ich kann keine statische Factory-Funktion finden. Mit der getPrivateKeyEncoded
Methode von ECKey
können wir jedoch ein DumpedPrivateKey
Objekt erhalten, das von abgeleitet ist VersionedChecksummedBytes
. Wir können auch die getPrivateKeyAsWiF
Methode verwenden, ECKey
die direkter ist. Oder wir können Dinge manuell tun:
import java.math.BigInteger;
import org.bitcoinj.core.VersionedChecksummedBytes;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Base58;
import org.bitcoinj.params.MainNetParams;
public class Test {
public static void main(String args[]){
NetworkParameters mainNet = MainNetParams.get();
String hex = "dba1e3e22415c56af772dee422add21b7382ea35f2af77852a8069d02e47ecf4";
BigInteger big = new BigInteger(hex, 16);
ECKey key = ECKey.fromPrivate(big, false); // uncompressed
byte[] priv = key.getPrivKeyBytes();
String wif1 = key.getPrivateKeyEncoded(mainNet).toBase58();
System.out.println(wif1); // 5KV1o7tRK8pNqrPNYyi38nrik9r2Y85sjdgFDttnDiT1uZrQ1fj
String wif2 = key.getPrivateKeyAsWiF(mainNet);
System.out.println(wif2); // 5KV1o7tRK8pNqrPNYyi38nrik9r2Y85sjdgFDttnDiT1uZrQ1fj
byte[] bytes = new byte[1 + 32 + 4];
bytes[0] = (byte) 0x80;
System.arraycopy(priv, 0, bytes, 1, 32);
byte[] checksum = Sha256Hash.hashTwice(bytes, 0, 33);
System.arraycopy(checksum, 0, bytes, 33, 4);
String wif3 = Base58.encode(bytes);
System.out.println(wif3); // 5KV1o7tRK8pNqrPNYyi38nrik9r2Y85sjdgFDttnDiT1uZrQ1fj
}
}
0x01
Beachten Sie, dass Sie, wenn Sie die gleiche manuelle Berechnung für einen komprimierten Schlüssel durchführen möchten, ein zusätzliches Byte nach dem 32-Byte-Geheimnis und direkt vor der Prüfsumme hinzufügen müssen . Wenn Sie dasselbe für ein Testnetzwerk tun möchten, ersetzen Sie das vordere Versionsbyte 0x80
durch 0xef
.
John unten
dave_thompson_085
Address
Klasse, die Ihr Code bereits verwendet - so habe ich es gefunden.John unten
John unten
dave_thompson_085
toBase58
(odertoString
das es einfach umschließt)String
.