{"id":16236,"date":"2021-01-28T03:06:33","date_gmt":"2021-01-28T02:06:33","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=16236"},"modified":"2021-06-27T06:40:13","modified_gmt":"2021-06-27T04:40:13","slug":"java-bitcoin-bip39-mnemonic-generierung-mit-adressen-mit-java-auf-einem-raspberry-pi-in-1-minute-crypto-bpmn","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=16236","title":{"rendered":"Java Bitcoin: BIP39 Mnemonic Generierung mit Adressen mit Java auf einem Raspberry Pi in 1 Minute &#8211; Crypto BPMN"},"content":{"rendered":"<p>Wie kann man f\u00fcr Bitcoin die geheimen W\u00f6rter, private und public Key und Adressen mit Java auf einem Raspberry Pi generieren? Hier mal ein Beispiel. Zuerst ein BPMN f\u00fcr den \u00dcberblick wie es l\u00e4uft.<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/01\/crypto-workflow-pi-scaled.jpeg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/01\/crypto-workflow-pi-scaled.jpeg\" alt=\"Bitcoin, key, crypto\" width=\"2560\" height=\"840\" class=\"aligncenter size-full wp-image-16237\" \/><\/a><\/p>\n<p>Das geht in 1 Minute, mit diesen drei Schritten auf der Komandozeile &#8230; <!--more--><\/p>\n<pre class=\"lang:default decode:true \" >\r\n\r\n# Das Projekt clonen \r\ngit clone https:\/\/github.com\/IT-Berater\/BIP39.git\r\n\r\n# in das Verzeichnis wechseln\r\ncd BIP39\/crypto-libs-distro\/\r\n\r\n# Programm starten\r\n.\/start-java.sh\r\n\r\n<\/pre>\n<p>Das Ergebnis:<br \/>\n<a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/01\/wenzlaff.de-2021-01-27-um-21.50.18.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/01\/wenzlaff.de-2021-01-27-um-21.50.18.png\" alt=\"\" width=\"3568\" height=\"2178\" class=\"aligncenter size-full wp-image-16244\" \/><\/a><\/p>\n<p>Der Java-Code:<\/p>\n<pre class=\"lang:java decode:true \" >package de.wenzlaff.beispiel;\r\n\r\nimport java.math.BigInteger;\r\nimport java.security.Provider;\r\nimport java.security.SecureRandom;\r\nimport java.security.Security;\r\n\r\nimport io.github.novacrypto.bip32.ExtendedPrivateKey;\r\nimport io.github.novacrypto.bip32.ExtendedPublicKey;\r\nimport io.github.novacrypto.bip32.networks.Bitcoin;\r\nimport io.github.novacrypto.bip39.MnemonicGenerator;\r\nimport io.github.novacrypto.bip39.MnemonicValidator;\r\nimport io.github.novacrypto.bip39.SeedCalculator;\r\nimport io.github.novacrypto.bip39.Words;\r\nimport io.github.novacrypto.bip39.Validation.InvalidChecksumException;\r\nimport io.github.novacrypto.bip39.Validation.InvalidWordCountException;\r\nimport io.github.novacrypto.bip39.Validation.UnexpectedWhiteSpaceException;\r\nimport io.github.novacrypto.bip39.Validation.WordNotFoundException;\r\nimport io.github.novacrypto.bip39.wordlists.English;\r\n\r\n\/**\r\n * Ausgabe der 24 BIP39 W\u00f6rter in englisch und der im System verwendeten\r\n * Security Provider. Beispiel f\u00fcr die Generierung der privaten und \u00f6ffentlichen\r\n * Key sowie die Adressen.\r\n * \r\n * Siehe auch online:\r\n * \r\n * https:\/\/iancoleman.io\/bip39\/\r\n * \r\n * http:\/\/bip39.de\/\r\n * \r\n * http:\/\/www.wenzlaff.info\r\n * \r\n * @author Thomas Wenzlaff\r\n *\/\r\npublic class Start {\r\n\r\n\t\/**\r\n\t * Optionales Passwort.\r\n\t *\/\r\n\tprivate static final String KEIN_BIP39_PASSWORT = \"\";\r\n\t\/**\r\n\t * Der BIP32 abgeleitete Pfad f\u00fcr BTC (Bitcoine)\r\n\t *\/\r\n\tprivate static final String BIP32_ABGELEITETER_PFAD = \"m\/0'\/0'\";\r\n\r\n\t\/**\r\n\t * Testcode.\r\n\t * \r\n\t * @param args\r\n\t * @throws Exception\r\n\t *\/\r\n\tpublic static void main(String[] args) throws Exception {\r\n\r\n\t\tSystem.out.println(\"Starte das erzeuge zuf\u00e4llige Wortliste mit 24 W\u00f6rtern\");\r\n\t\tString wortliste = get24Wortliste();\r\n\r\n\t\tSystem.out.println(\"\\n24 BIP39 Mnemonic W\u00f6rter in englisch:\");\r\n\t\tSystem.err.println(wortliste);\r\n\r\n\t\tSeedCalculator seedCal = new SeedCalculator();\r\n\t\tCharSequence bip39Passphrase = KEIN_BIP39_PASSWORT;\r\n\r\n\t\tSystem.out.println(\"\\nBIP39 optionale Passphrase (Achtung, nicht f\u00fcr alle Ger\u00e4te (ledgers) erlauben eine Passphrase\");\r\n\t\tSystem.out.println(\"Verwende Passwort f\u00fcr BIB39 Seed:\");\r\n\t\tSystem.err.println(bip39Passphrase);\r\n\r\n\t\tSystem.out.println(\"Berechne aus BIP39 Wortliste und optionalen Passphrase den Seed\");\r\n\t\tbyte[] calculateSeed = seedCal.calculateSeed(wortliste, bip39Passphrase.toString());\r\n\r\n\t\tSystem.out.println(\"\\nBIP39 Seed in Hex:\");\r\n\t\tSystem.err.println(encodeBytesToHex(calculateSeed));\r\n\r\n\t\tSystem.out.println(\"\\nBerechne mit dem Seed und den Coin (BTC - Bitcoin) den BIP 32 privaten Schl\u00fcssel\");\r\n\r\n\t\tExtendedPrivateKey privateKey = ExtendedPrivateKey.fromSeed(calculateSeed, Bitcoin.MAIN_NET);\r\n\t\tString extendedKey = privateKey.extendedBase58();\r\n\r\n\t\tSystem.out.println(\"\\nBIP32 private Key f\u00fcr Bitcoin(BTC) (BIP32 Root Key, BIP32 Wurzelschl\u00fcssel):\");\r\n\t\tSystem.err.println(extendedKey);\r\n\r\n\t\t\/\/ BIP32 Erweiterter Privatschl\u00fcssel\r\n\t\tSystem.out.println(\r\n\t\t\t\t\"\\nLeite vom privaten Key und BIP32-abgeleiteten Pfad (\" + BIP32_ABGELEITETER_PFAD + \") (Bitcoin Core) den erweiterten privaten Schl\u00fcssel ab\");\r\n\t\tExtendedPrivateKey abgeleiteterPrivateKey = privateKey.derive(BIP32_ABGELEITETER_PFAD);\r\n\t\tSystem.out.println(\"\\nBIP32 Erweiterter Privatschl\u00fcssel:\");\r\n\t\tSystem.err.println(abgeleiteterPrivateKey.extendedBase58());\r\n\r\n\t\t\/\/ BIP32 Erweiterter \u00f6ffentlicher Schl\u00fcssel\r\n\t\tExtendedPublicKey abgeleiteterPublicKey = abgeleiteterPrivateKey.neuter();\r\n\t\tSystem.out.println(\"\\nBIP32 Erweiterter \u00f6ffentlicher Schl\u00fcssel:\");\r\n\t\tSystem.out.println(abgeleiteterPublicKey.extendedBase58());\r\n\r\n\t\t\/\/ Abgeleitete Adressen\r\n\t\t\/\/ Beachten Sie, dass diese Adressen vom erweiterten BIP32-Schl\u00fcssel abgeleitet\r\n\t\t\/\/ sind, und nun mal drei Adressen ausgeben\r\n\r\n\t\tSystem.out.println(\"\\nAdressen:\");\r\n\t\tString addressMethod = privateKey.derive(\"m\/0'\/0'\/0\").neuter().p2pkhAddress();\r\n\t\tSystem.out.println(\"0. Adresse: \" + addressMethod);\r\n\t\taddressMethod = privateKey.derive(\"m\/0'\/0'\/1\").neuter().p2pkhAddress();\r\n\t\tSystem.out.println(\"1. Adresse: \" + addressMethod);\r\n\t\taddressMethod = privateKey.derive(\"m\/0'\/0'\/2\").neuter().p2pkhAddress();\r\n\t\tSystem.out.println(\"2. Adresse: \" + addressMethod);\r\n\t}\r\n\r\n\tprivate static String encodeBytesToHex(byte[] bytes) {\r\n\t\tBigInteger bigInteger = new BigInteger(1, bytes);\r\n\t\treturn bigInteger.toString(16);\r\n\t}\r\n\r\n\tprivate static String get24Wortliste() throws InvalidChecksumException, InvalidWordCountException, WordNotFoundException, UnexpectedWhiteSpaceException {\r\n\r\n\t\tSecureRandom secureRan = new SecureRandom();\r\n\t\tSystem.out.println(\"Verwende Provider: \" + secureRan.getProvider().getInfo());\r\n\r\n\t\tbyte[] entropy = new byte[Words.TWENTY_FOUR.byteLength()];\r\n\r\n\t\tsecureRan.nextBytes(entropy);\r\n\r\n\t\tStringBuilder sb = new StringBuilder();\r\n\t\tnew MnemonicGenerator(English.INSTANCE).createMnemonic(entropy, sb::append);\r\n\r\n\t\tMnemonicValidator.ofWordList(English.INSTANCE).validate(sb.toString());\r\n\r\n\t\treturn sb.toString();\r\n\t}\r\n\r\n\tprivate static Provider[] getSecurityProviders() {\r\n\t\tSystem.out.println(\"Alle \" + Security.getProviders().length + \" im System bekannten Security Provider:\");\r\n\t\tProvider[] provider = Security.getProviders();\r\n\t\tfor (int i = 0; i &lt; provider.length; i++) {\r\n\t\t\tSystem.out.println(provider[i].getInfo());\r\n\t\t}\r\n\t\treturn provider;\r\n\t}\r\n}\r\n<\/pre>\n<p>Es kann das <strong>BIP39\/crypto-libs-distro\/<\/strong> Verzeichnis auch auf einem USB-Stick kopiert werden und dann auf einen &#8222;frischen&#8220; Pi, der keine Verbindung zum Internet hat die Keys erzeugt werden. Nach der Key-Erzeugung die 24 W\u00f6rter abschreiben und sicher aufbewahren. Dann kann der Pi und der USB-Stick &#8222;platt&#8220; gemacht werden.<\/p>\n<p>Alles nat\u00fcrlich nur f\u00fcr Demo-Zwecke und ohne Gew\u00e4hr, wer will kann die Schl\u00fcssel auch http:\/\/bip39.de\/ zu Testzwecken vergeleichen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wie kann man f\u00fcr Bitcoin die geheimen W\u00f6rter, private und public Key und Adressen mit Java auf einem Raspberry Pi generieren? Hier mal ein Beispiel. Zuerst ein BPMN f\u00fcr den \u00dcberblick wie es l\u00e4uft. Das geht in 1 Minute, mit diesen drei Schritten auf der Komandozeile &#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[220,1430,5,3897,79,1023,1319],"tags":[910,4601,4602,4603,4600,1183,2194,4597,2178,819,380,4598,4604,4599,176,1020,4605],"class_list":["post-16236","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-bpmn","category-java","category-java-programmierung","category-programmierung","category-raspberry-pi","category-sicherheit-2","tag-adresse","tag-bip","tag-bip32","tag-bip39","tag-bip39-de","tag-bitcoin","tag-bpmn","tag-crypto","tag-java","tag-key","tag-passwort","tag-privat-key","tag-root-key","tag-seed","tag-sicherheit","tag-verschluesselung","tag-wurzelschluessel"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/16236","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16236"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/16236\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16236"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}