Wie werden Ethereum-Adressen generiert?

Welche Kriterien muss eine gültige Ethereum-Adresse erfüllen? Ist es nur eine Zufallszahl in Hexadezimal? Oder muss es gemäß einigen kryptografischen Algorithmen auf eine bestimmte Weise abgeleitet werden? Welche Algorithmen und Standards werden verwendet, um das Schlüsselpaar zu generieren?

Ich bin mit dem Duplikat nicht einverstanden. Bei der Frage geht es nicht darum, zu überprüfen, ob die Adresse gültig ist, sondern wie die Adresse aufgebaut ist und ob sie einem Format folgt oder nur zufällig ist. Tatsächlich ist es kein Zufall, sondern das Ergebnis einiger Prozesse. Die Tatsache, dass das Wort „gültig“ in der Frage steht, ist kein Kriterium, Sie werden nicht alle Fragen mit dem Wort „gültig“ als Duplikate markieren!
@tayvano Ich bin nicht derjenige, der diese Frage gestellt hat
Es ist völlig in Ordnung, dass Fragen bearbeitet/verbessert und für die Wiedereröffnung gestimmt werden. Auf geht's.
Es könnte sich lohnen, die Kommentare auf mögliche Betrüger hinzuweisen, da sie den Wert haben, denjenigen von uns, die lernen, eine andere Perspektive zu bieten.

Antworten (6)

Kürzlich wurde ich auf diesen Artikel aufmerksam, der viel ausführlicher und technischer ist als meine zugänglichere Version unten. Es führt Sie auch durch die Erstellung eines eigenen. Ich kann es nur empfehlen: https://kobl.one/blog/create-full-ethereum-keypair-and-address/


Aus dem Gelben Papier

gelbes Papier

Es gibt drei Hauptschritte, um von privat -> Adresse zu gelangen:

  1. Erstellen Sie einen zufälligen privaten Schlüssel (64 (Hex) Zeichen / 256 Bits / 32 Bytes)

  2. Leiten Sie den öffentlichen Schlüssel von diesem privaten Schlüssel ab (128 (hex) Zeichen / 512 Bits / 64 Bytes)

  3. Leiten Sie die Adresse von diesem öffentlichen Schlüssel ab. (40 (hex) Zeichen / 160 Bit / 20 Byte)

Auch wenn viele Leute die Adresse den öffentlichen Schlüssel nennen, ist dies bei Ethereum eigentlich nicht der Fall. Es gibt einen separaten öffentlichen Schlüssel, der als Mittelsmann fungiert, den Sie nie sehen werden, es sei denn, Sie stöbern in einer JSON-Datei einer Brieftasche vor dem Verkauf.

1. Generieren des privaten Schlüssels

Der private Schlüssel besteht aus 64 Hexadezimalzeichen. Jede einzelne Zeichenfolge von 64 Hex ist hypothetisch ein privater Ethereum-Schlüssel (siehe Link oben, warum dies nicht ganz genau ist) , der auf ein Konto zugreift. Wenn Sie vorhaben, ein neues Konto zu erstellen, sollten Sie sicherstellen, dass diese mit einem geeigneten RNG ausgestattet sind. Sobald Sie diese Zeichenfolge haben.

2. Privater Schlüssel -> Öffentlicher Schlüssel

Das ist hart und überfordert mich. Es gibt etwas mit Elliptic Curve Digital Signature Algorithm (ECDSA) und so. Aber am Ende haben Sie einen öffentlichen Schlüssel, der 64 Bytes groß ist.

3. Öffentlicher Schlüssel -> Adresse

  1. Beginnen Sie mit dem öffentlichen Schlüssel (128 Zeichen / 64 Bytes)

  2. Nehmen Sie den Keccak-256-Hash des öffentlichen Schlüssels. Sie sollten jetzt eine Zeichenfolge mit 64 Zeichen / 32 Bytes haben. (Hinweis: SHA3-256 wurde schließlich zum Standard, aber Ethereum verwendet Keccak)

  3. Nehmen Sie die letzten 40 Zeichen / 20 Bytes dieses öffentlichen Schlüssels (Keccak-256). Oder anders gesagt, lassen Sie die ersten 24 Zeichen / 12 Bytes weg. Diese 40 Zeichen / 20 Bytes sind die Adresse. Wenn 0x vorangestellt wird, wird es 42 Zeichen lang.

Definitionen

Adresse: Eine Ethereum-Adresse repräsentiert ein Konto. Für EOA wird die Adresse als die letzten 20 Bytes des öffentlichen Schlüssels abgeleitet, der das Konto steuert, z. B. `cd2a3d9f938e13cd947ec05abc7fe734df8dd826. Dies ist ein hexadezimales Format (Basis-16-Notation), das häufig explizit durch das Anhängen von 0x an die Adresse angegeben wird. Web3.js und Konsolenfunktionen akzeptieren Adressen mit oder ohne dieses Präfix, aber aus Gründen der Transparenz empfehlen wir ihre Verwendung. Da jedes Byte der Adresse durch 2 Hexadezimalzeichen dargestellt wird, ist eine vorangestellte Adresse 42 Zeichen lang. Mehrere Apps und APIs sollen auch das neue prüfsummenfähige Adressschema implementieren, das in der Mist Ethereum Wallet ab Version 0.5.0 eingeführt wurde. - Homestead-Dokumente

Privater Schlüssel: Eine zufällig ausgewählte positive Ganzzahl (dargestellt als Byte-Array der Länge 32 in Big-Endian-Form) im Bereich [1, secp256k1n − 1]. - Gelbes Papier

Was ist die Logik dahinter, nur die letzten 20 Bytes des Hashs zu verwenden?
@k26dr Jede Krypto scheint etwas Ähnliches zu tun, um Adressen eindeutig zu halten (damit Sie Bitcoin nicht an eine ETH-Adresse senden usw.). Ich kenne jedoch den genauen Grund nicht. Wäre aber eine tolle neue Frage. Es ist unwahrscheinlich, dass Sie hier eine wirkliche Antwort erhalten.
@k26dr Es geht nur darum, die Adressen so kurz wie möglich zu halten, ohne das Risiko von Kollisionen einzugehen.
Gute Informationen - Aber die endgültige (optionale) Prüfsumme für Großbuchstaben wurde nicht so erklärt, wie Sie es hier getan haben. ethereum.stackexchange.com/a/2046/22785 Dies ist auch Teil der öffentlichen Adressgenerierung.
Hier steht: ethdocs.org/en/latest/… dass der private Schlüssel mit dem Passwort des Benutzers verschlüsselt wird, scheint dies in dieser Antwort nicht erwähnt zu werden?
@MartinDawson Die Antwort sagt Ihnen, wie die Schlüssel generiert werden (und es ist richtig). Nachdem Sie die privaten/öffentlichen Schlüssel generiert haben, müssen Sie sie an einem sicheren Ort aufbewahren. Dafür ist die passwortverschlüsselte Datei da.
@k26dr Ich vermute, dass ein weiterer Grund für die Kürzung der Adresse auf 160 Bit darin bestand, dass Kademlia DHT p2p-Knoten 160 Bit laut Spezifikation sind und wenn ich mich richtig erinnere, sollten Ethereum-Knoten ihre Adresse als ihre Kademlia-Knoten-ID angeben.
Gibt es eine offizielle* Open-Source-Software, um einfach die privaten Schlüssel und die öffentlichen Schlüssel zu generieren? (*Hergestellt von den Jungs, die die ETH gegründet haben)

Privater Schlüsselraum:

Hier sind einige Codebeispiele, basierend auf der von Ethereum verwendeten elliptischen Kurve secp256k1, wie andere angemerkt haben, damit der 256-Bit-Schlüssel gültig ist, muss er kleiner sein als der Parameter der Kurve, nder auch ein 256-Bit-Wert sein kann im Hexadezimalformat geschrieben werden als:0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

Fehlerüberprüfung:

Verschiedene Bibliotheken erzeugen Fehler, wenn Sie versuchen, ihnen einen privaten Schlüssel zuzuführen, der größer ist als n, als Fehlerprüfmechanismus (dh Exception: Invalid privkey) Weitere Informationen finden Sie in dieser verwandten Antwort mit Beispielen .

Verwandte Kurvenparameter:

Wir können den privaten Schlüssel sals geheimen Exponenten bezeichnen, da dieser Wert die Kurve mit dem Parameter g(unter Verwendung der Skalarmultiplikation) umschließt, der einen öffentlichen Generatorpunkt bezeichnet, der wie eine universelle Konstante ist, die jeder kennt und verwendet, um generieren ihren öffentlichen Schlüssel aus s.

Bleibt also göffentlich, smuss aber geheim gehalten werden, damit die Ethereum-Brieftasche sicher bleibt, nachdem Ihre Ethereum-Adresse von Ihrem öffentlichen Schlüssel abgeleitet wurde.

Der öffentliche Schlüssel kann entweder in einem komprimierten Format mit einer Gesamtlänge von 33 Bytes oder unkomprimiert als 64 Bytes dargestellt werden und wird normalerweise durch ein führendes Präfix 0x02 für komprimierte öffentliche Schlüssel gekennzeichnet, aber die Länge der Zeichenfolge ist ein besserer Indikator als das Präfix je nach Schritt und Implementierung auch nicht sichtbar oder vorhanden.

Kryptografisch sichere Schlüsselableitung:

Auch shinsichtlich der kryptografischen Sicherheit spielt die gewählte Art eine große Rolle. Mit anderen Worten, es ist nicht ratsam, diesen geheimen Exponenten selbst zu wählen oder sich irgendeine clevere Methode auszudenken, wie Sie es für ein Passwort (auch bekannt als Brain Wallet) tun könnten, da unzählige solcher Methoden seit Jahrzehnten verwendet werden, um Geheimnisse mit verschiedenen Algorithmen zu knacken und Computersoftware, wie sie zum Knacken von Passwörtern verwendet werden.

Daher sollte der geheime Exponent mit einem kryptografisch sicheren Pseudozufallszahlengenerator (CSPRNG) wie der WorldWideWeb Consortium (W3C) Cryptography API ( Offenlegung: Ich bin einer von 12 Mitwirkenden an dieser Spezifikation auf Github ) generiert werden, damit dort Es ist weit weniger wahrscheinlich, dass ein Angreifer diesen Wert vorhersagen könnte, da die zufälligen Bits, aus denen diese Zahl besteht, von verschiedenen Stellen Ihres lokalen Geräts und von Prozessen stammen, die diese Entropiedaten nicht online übertragen (vorausgesetzt, die Software, die Sie verwenden verwenden, ist zusammen mit einem sicheren CSPRNG sicher).

Beispiel Python-Code:

Bei Verwendung von Python 3 gibt es ein CSPRNG in der Secrets-Bibliothek, das so einfach sein kann wie das Ausführen der folgenden Befehle in der Reihenfolge vom IDLE-Interpreter oder einer .py-Datei nach dem Importieren der Secrets-Bibliothek:

secrets.randbits(256)

Der obige Befehl erzeugt eine 256-Bit-Binärzahl, die als privater Schlüssel verwendet werden kann, wenn sie kleiner als der Wert von nist, aber sie muss als Bytes-Objekt im Python-Implementierungsbeispiel unten formatiert werden, indem die eth-keysBibliothek aus der verwendet wird Ethereum Foundation Github-Repository (Das folgende Beispiel erfordert möglicherweise die Installation der sha3Bibliothek ( pip install pysha3 ), die Keccak enthält, falls nicht in der Standardbibliothek vorhanden hashlib):

import secrets
import sha3
import eth_keys
from eth_keys import keys

private_key = str(hex(secrets.randbits(256))[2:])
private_key_bytes = bytes.fromhex(private_key)
public_key_hex = keys.PrivateKey(private_key_bytes).public_key
public_key_bytes = bytes.fromhex(str(public_key_hex)[2:])
Keccak256_of_public_key_bytes = sha3.keccak_256(public_key_bytes).hexdigest()
public_address = keys.PublicKey(public_key_bytes).to_address()


print('\n Private_key:',private_key,
      '\n Private_key_bytes:',private_key_bytes,
      '\n Public_key_hex:',public_key_hex,
      '\n Public_key_bytes:',public_key_bytes,
      '\n Full_Keccak_digest:',Keccak256_of_public_key_bytes,
      '\n Ethereum address:',public_address)

Beispielausgabe des obigen Codes (nicht im Hauptnetz zu verwenden, nur zum Beispiel)

 Private_key: 7231bfb75a41481965e391fb6d4406b6c356d20194c5a88935151f05136d2f2e 
 Private_key_bytes: b'r1\xbf\xb7ZAH\x19e\xe3\x91\xfbmD\x06\xb6\xc3V\xd2\x01\x94\xc5\xa8\x895\x15\x1f\x05\x13m/.' 
 Public_key_hex: 0x013e81c4a44c5303b11452f649be9427b75605339d8eba90f8e99cc401a8bd4f7494e0d0740bcc0282af75f9bd4571ed493a05ed02f1b968a45a46f4d77be149 
 Public_key_bytes: b"\x01>\x81\xc4\xa4LS\x03\xb1\x14R\xf6I\xbe\x94'\xb7V\x053\x9d\x8e\xba\x90\xf8\xe9\x9c\xc4\x01\xa8\xbdOt\x94\xe0\xd0t\x0b\xcc\x02\x82\xafu\xf9\xbdEq\xedI:\x05\xed\x02\xf1\xb9h\xa4ZF\xf4\xd7{\xe1I" 
 Full_Keccak_digest: 3f54dd68163875b594cfdc8e8a2250aafb31638b19a83caa49d1ee61089dcb4b 
 Ethereum address: 0x8a2250aafb31638b19a83caa49d1ee61089dcb4b

Sechs Schritte vom privaten Schlüssel zur Ethereum-Adresse

Wie in der obigen Implementierung, die ich geschrieben habe, zu sehen ist, können die sechs Schritte vom privaten Schlüssel zur Ethereum-Adresse wie folgt zusammengefasst werden:

  1. Generieren Sie eine sichere 256-Bit-Zahl im Hexadezimalformat, die in eine Zeichenfolge konvertiert wird, wobei das Präfix 0x verworfen wird.
  2. Konvertieren Sie den in Schritt 1 generierten Hex-String in ein Bytes-Objekt (b"").
  3. Berechnen Sie den öffentlichen Schlüssel als Hex unter Verwendung des in Schritt 2 erstellten Bytes-Objekts des privaten Schlüssels.
  4. Konvertieren Sie den in Schritt 3 generierten öffentlichen Hex-Schlüssel in ein Bytes-Objekt.
  5. Berechnen Sie den Hash-Digest des in Schritt 4 erstellten Bytes-Objekts mit Keccak_256.
  6. Nehmen Sie die ganz rechten/letzten 40 Hexadezimalzeichen (nachlaufende 160 Bit auf der Little-Endian-Seite) des in Schritt 5 erstellten Hash-Digest, der zur abgeleiteten Ethereum-Adresse wird.

Alternative Abhängigkeiten:

Zusätzlich zu der Open-SSL-Bibliothek , auf die in dem Artikel verwiesen wird, auf den @tayvano hingewiesen hat, umfassen andere Bibliotheken, die zur Berechnung öffentlicher Adressen von elliptischen Kurven verwendet werden können, die ecdsa-Python-Bibliothek und die in C geschriebene secp256k1-Bibliothek von Bitcoin, obwohl letztere Tools zur Formatierung enthalten wird Bitcoin-Adressen, die sich aufgrund der Formatierungsschritte und unterschiedlichen Hash-Algorithmen und Codierungsmethoden völlig von Ethereum-Adressen unterscheiden, auch wenn der zugrunde liegende private Schlüssel und der öffentliche Schlüssel zum Beispiel gleich sind.

Hinweis: Schließlich ist es wichtig, Tests durchzuführen, um sicherzustellen, dass eine generierte Adresse nicht nur gültig ist, sondern dass der zugrunde liegende private Schlüssel, der im Prozess verwendet wird, zum Signieren von Transaktionen gültig ist (dh wenn ein Benutzer einen Hash-Digest der Byte-Array, das als String statt als Bytes-Objekt behandelt wird, was zu einem falschen Hash-Digest und damit zu einer falschen Adresse für den zugrunde liegenden Schlüssel führt).

Beispiel : Ein solches Tool zur Adressüberprüfung (Prüfsumme) aus der eth-keys-Bibliothek ist der folgende Befehl: keys.PublicKey().to_checksum_address()der die Bytes des öffentlichen Schlüssels verwendet (dh die Übergabe der Variablen in die erste Klammer würde im obigen Programm sicher public_key_bytesso aussehen keys.PublicKey(public_key_bytes).to_checksum_address()berechnete Adresse ist korrekt). Aus diesem Grund kann die Verwendung vorhandener Bibliotheken sicherer sein, als den Code von Grund auf neu zu schreiben.

PS Antworten und Beispiele sollen nicht alle Risiken/Schritte erschöpfend darstellen.

Sollten wir bei der ETH HD-Wallet-Generierung (Ableitung des untergeordneten Schlüssels aus dem Pfad m/44'/60/0/x) einen "komprimierten" oder "unkomprimierten" öffentlichen Schlüssel verwenden?
Sieht so aus, als würden "komprimierte" 33 Byte verwendet
Betreff. den Kommentar zum geheimen Schlüssel relativ zum elliptischen Kurvenparameter nfinden Sie unter: eips.ethereum.org/EIPS/eip-1271 : „Wenn Ihre Bibliothek formbare Signaturen generiert, wie z. B. s-Werte im oberen Bereich, berechnen Sie einen neuen S-Wert mit 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1und wechseln Sie vvon 27zu 28oder umgekehrt. Wenn Ihre Bibliothek auch Signaturen mit 0/ 1für vstatt 27/ generiert 28, fügen Sie 27zu hinzu v, um diese formbaren Signaturen ebenfalls zu akzeptieren."

Ethereum-Adressen sind Hashes eines öffentlichen Schlüssels. Um einen zu generieren, müssen Sie also zuerst einen privaten Schlüssel generieren (siehe: Was ist der Ansatz, um eine Ethereum-Adresse aus einem 256-Bit-Private-Key zu berechnen? ) Der private Schlüssel ist zufällig, aber der öffentliche Schlüssel und damit sein Hash wird als Adresse verwendet nicht zufällig.

Um eine Adresse zu überprüfen und somit das Format zu kennen, siehe Wie kann ich überprüfen, ob eine Ethereum-Adresse gültig ist?

Okay! Ein paar kurze Fragen: 1) Die privaten und öffentlichen Schlüssel: Welcher Verschlüsselungsalgorithmus wird verwendet? Ist es das gleiche wie bei Bitcoin? (secp256k1 ECDSA glaube ich) 2) Die Adresse: Es ist ein Hash des öffentlichen Schlüssels. Welche Hashfunktion wird verwendet? SHA256?
Ja und ja, aber mit keccak256. Aber Sie sollten dies in einer anderen Frage stellen und diese als beantwortet markieren, wenn Sie der Meinung sind, dass die ursprüngliche Frage beantwortet ist.
Es waren eigentlich diese Fragen im Kommentar, die ich beantwortet haben wollte (wie die Adresse generiert wird, welche Algorithmen usw.). Wenn Sie es der Antwort hinzufügen, werde ich es als beantwortet markieren! Ich werde meine ursprüngliche Frage etwas präzisieren.
;) Kläre erstmal deine Frage. Es ist schwer, auf Fragen, die nicht einmal gestellt werden, klare Antworten zu geben.
Nur-Link-Fragen werden nicht empfohlen.
Ich dachte, es sei nur ein Problem für Links außerhalb von Stack-Sites. Aber inner sollte in Ordnung sein, da das Ziel sichtbar sein sollte, wenn der Link sichtbar ist. Es ist nur ein Problem für Leute, die Webseiten drucken, aber das sollte niemand tun.

Falls jemand nach einer JS-Lösung sucht:

const Web3 = require('web3')
const web3 = new Web3()
const elliptic = require('elliptic')
const ec = new elliptic.ec('secp256k1')


function pubKeyToAddress(compressedPubkey) {
  let keyPair = ec.keyFromPublic(compressedPubkey, 'hex')
  // remove '04' then add prefix '0x'
  let pubkey = '0x' + keyPair.getPublic(false, 'hex').substr(2)
  let address = trimFirst12Bytes(web3.utils.keccak256(pubkey))
  return web3.utils.toChecksumAddress(address)
}
unction trimFirst12Bytes(hexString) {
  return '0x'.concat(hexString.substr(hexString.length - 40))
}

Hier ist ein Python-Paket, das in PyPI gehostet wird: eth_address_dump

Eth-Adresse aus privatem Schlüssel ausgeben:

$ echo "0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105" | eth_address_dump
private_key = 0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073

Eth-Adresse aus mnemonischen Wörtern ausgeben:

$ echo "olympic wine chicken argue unaware bundle tunnel grid spider slot spell need" | eth_address_dump
mnemonic = olympic wine chicken argue unaware bundle tunnel grid spider slot spell need
private_key = 0x6ee825aafad19a0d759e1e0ba61d0c523b7b23038998a92d7904458b91667105
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073

Eth-Adresse aus komprimiertem öffentlichen Schlüssel ausgeben:

$ echo "0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f" | eth_address_dump
public_key = 0xaa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9fe85fc162e43d721533736d79c102139d3035d2d9251ccf809bc5bddb81cc6563
compressed_public_key = 0x03aa3e0b3f86053c2aaa08d6f6398e18f76100e0d675680228b000c252e4393e9f
address = 0xF7dcf60AebA077461862d51b77d6d804C06E0073
  • Zunächst wird ein zufälliger privater Schlüssel aus 64 (hex) Zeichen (256 Bit / 32 Byte) generiert.

  • Ein öffentlicher Schlüssel mit 128 (Hex) Zeichen (512 Bit / 64 Byte) wird dann aus dem generierten privaten Schlüssel unter Verwendung des Elliptic Curve Digital Signature Algorithm ( ECDSA ) abgeleitet.

  • Die Keccak-256- Hash-Funktion wird dann auf den öffentlichen Schlüssel angewendet, um eine Hash-Zeichenkette mit 64 Zeichen (256 Bit / 32 Byte) zu erhalten. Die letzten 40 Zeichen dieser Zeichenfolge mit dem Präfix 0x werden zur endgültigen Ethereum-Adresse. (Hinweis: 0x in der Codierung zeigt an, dass die Zahl/String in Hex geschrieben ist.)

Quelle


Hinweis: Für eine detailliertere, aber einfache mathematische Erklärung dieser Schritte lesen Sie bitte diesen sehr nützlichen Artikel . Wenn Sie tiefer in das Konzept eintauchen möchten, lesen Sie dieses Buch .


Einfaches Python-Codebeispiel mit dem Modul eth_account

from eth_account import Account

acc = Account.create(password_string)
prv = acc.key
pub = Account._parsePrivateKey(prv).public_key
addr = acc.address