{"id":16312,"date":"2021-02-14T03:38:00","date_gmt":"2021-02-14T02:38:00","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=16312"},"modified":"2021-02-24T08:38:34","modified_gmt":"2021-02-24T07:38:34","slug":"pkh","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=16312","title":{"rendered":"Bitcoin: Public Key hashen mit  SHA-256 und dann RIPEMD-160"},"content":{"rendered":"<figure id=\"attachment_16314\" aria-describedby=\"caption-attachment-16314\" style=\"width: 2560px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-scaled.jpg\" alt=\"\" width=\"2560\" height=\"1919\" class=\"size-full wp-image-16314\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-scaled.jpg 2560w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-300x225.jpg 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-1024x768.jpg 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-768x576.jpg 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-1536x1151.jpg 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/Pech-2048x1535.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><figcaption id=\"caption-attachment-16314\" class=\"wp-caption-text\">public key hash f\u00fcr bitcoin<\/figcaption><\/figure>\n<p>Der public Key wird zun\u00e4chst mit <a href=\"https:\/\/de.wikipedia.org\/wiki\/SHA-2\" rel=\"noopener\" target=\"_blank\">SHA-256<\/a> gehasht. Der Output dieser kryptografischen Hashfunktion wird dann mit RIPEMD-160 gehasht, einer anderen kryptografischen Hashfunktion, die als Output eine 160 Bit (20 Byte) lange Zahl erzeugt. Wir nennen diesen letzten Hash den public Key Hash (PKH). Wie hier im BPMN Flow dargestellt: &#8230;<!--more--><\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/wenzlaff.de-2021-02-13-um-21.38.14.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/02\/wenzlaff.de-2021-02-13-um-21.38.14.png\" alt=\"\" width=\"1100\" height=\"612\" class=\"aligncenter size-full wp-image-16313\" \/><\/a><\/p>\n<p>Aber warum verwendtet man bei Bitcoin <a href=\"https:\/\/de.wikipedia.org\/wiki\/SHA-2\" rel=\"noopener\" target=\"_blank\">SHA-256<\/a> und dann <a href=\"https:\/\/de.wikipedia.org\/wiki\/RIPEMD-160\" rel=\"noopener\" target=\"_blank\">RIPEMD-160<\/a>?<\/p>\n<p>RIPEMD160 als letzten kryptografischen Hash zu benutzen ist wahrscheinlich gew\u00e4hlt wurden, damit die PKHs m\u00f6glichst kurz werden. Es ist ein gut balancierter Tradeoff zwischen Sicherheit und Gr\u00f6sse. <\/p>\n<p>Es k\u00f6nnte sich auch, wenn eine der Hashfunktionen sich als nicht <a href=\"https:\/\/de.wikipedia.org\/wiki\/Preimage-Angriff\" rel=\"noopener\" target=\"_blank\">Pre-Image resistent<\/a> herausstellen w\u00fcrde, die andere es immer noch sein. Wenn man also einen Input f\u00fcr <a href=\"https:\/\/de.wikipedia.org\/wiki\/RIPEMD-160\" rel=\"noopener\" target=\"_blank\">RIPEMD-160<\/a> berechnen k\u00f6nnte, der einen bestimmten PKH Output ergibt, dann m\u00fcsste man immer noch eine <a href=\"https:\/\/de.wikipedia.org\/wiki\/Preimage-Angriff\" rel=\"noopener\" target=\"_blank\">Pre-Image Attacke<\/a> gegen SHA256  ausf\u00fchren, um den public Key zu finden. Ebenso m\u00fcsste man, wenn man einen Input f\u00fcr <a href=\"https:\/\/de.wikipedia.org\/wiki\/SHA-2\" rel=\"noopener\" target=\"_blank\">SHA-256<\/a> finden k\u00f6nnte, der einen bestimmten Output erzeugt, immer noch erst eine <a href=\"https:\/\/de.wikipedia.org\/wiki\/Preimage-Angriff\" rel=\"noopener\" target=\"_blank\">Pre-Image Attacke<\/a> auf RIPEMD-160 ausf\u00fchren, bevor man das Ergebnis zur Berechnung des public Keys hernehmen kann.<!--more--><\/p>\n<p>Es gibt ausserdem noch zu bedenken, dass unterschiedliche Organisationen die beiden kryptografischen Hashfunktionen entwickelt haben. <a href=\"https:\/\/de.wikipedia.org\/wiki\/RIPEMD-160\" rel=\"noopener\" target=\"_blank\">RIPEMD-160<\/a> wurde an einer Europ\u00e4ischen Universit\u00e4t in offener Kollaboration mit einer grossen Gemeinde von Kryptografen entwickelt. <a href=\"https:\/\/de.wikipedia.org\/wiki\/SHA-2\" rel=\"noopener\" target=\"_blank\">SHA-256<\/a> wurde von der US National Security Agency (NSA) entwickelt.<\/p>\n<p>Hier mal eine kleine Implementierung in Java, als kleines kommentiertes Beispiel.<\/p>\n<pre class=\"lang:java decode:true \" >package de.wenzlaff.twhash;\r\n\r\nimport io.nayuki.bitcoin.crypto.Ripemd160;\r\nimport io.nayuki.bitcoin.crypto.Sha256;\r\nimport io.nayuki.bitcoin.crypto.Sha256Hash;\r\n\r\n\/**\r\n * Bitcoin - Hashen des public Key zum PKH (public Key Hash)\r\n * \r\n * Vorteil: K\u00fcrzer (von 33 auf 20 Byte, gleich 13 Byte gespart) und\r\n * verschleierter den public Key.\r\n * \r\n * @author Thomas Wenzlaff\r\n *\/\r\npublic final class PublicKeyHash {\r\n\r\n\t\/**\r\n\t * Public Key zu PKH\r\n\t * \r\n\t * @param args optional der public Key (33 Byte) oder wenn keiner \u00fcbergeben wird\r\n\t *             ein Beispiel Key verwendet\r\n\t *\/\r\n\tpublic static void main(String[] args) {\r\n\r\n\t\tSystem.out.println(\"Public Key (von Bitcoin 33 Byte) zum PKH (public Key Hash 20 Byte) transformieren:\\n\");\r\n\r\n\t\tString publicKey = null;\r\n\t\tif (args != null &amp;&amp; args.length == 1) {\r\n\t\t\tpublicKey = args[0];\r\n\t\t} else {\r\n\t\t\t\/\/ public Key 33 Byte oder 66 Hex Zeichen z.B.\r\n\t\t\t\/\/ 0326d92f3db1cfc3b158f5c97425dba8961e95f30c40d1c0e69efc5ac89d8d6ba2\r\n\t\t\tSystem.out.println(\"Verwende Beispiel public Key, da keiner \u00fcbergeben wurde\");\r\n\t\t\tpublicKey = \"0326d92f3db1cfc3b158f5c97425dba8961e95f30c40d1c0e69efc5ac89d8d6ba2\";\r\n\t\t}\r\n\r\n\t\tSystem.out.println(\"Public Key (33 Byte):              \" + publicKey);\r\n\r\n\t\t\/\/ 1. SHA 256\r\n\t\tSha256Hash sha256Hash = Sha256.getHash(publicKey.getBytes());\r\n\r\n\t\t\/\/ 32 Byte oder 64 Hex Zeichen z.B.\r\n\t\t\/\/ af5c9a40eaacdbbb6ca346143ddaba7e22a099e0fd567f3318945ebc6297917c\r\n\t\tSystem.out.println(\"1. SHA-256 Hash erzeugen\");\r\n\t\tSystem.out.println(\"SHA-256 Hash (32 Byte):            \" + sha256Hash);\r\n\r\n\t\t\/\/ 2. RIPEMD-160\r\n\t\tbyte[] pkh = Ripemd160.getHash(sha256Hash.toBytes());\r\n\t\tSystem.out.println(\"2. RIPEMD-160 Hash erzeugen\");\r\n\t\t\/\/ 20 Byte oder 160 Bit PKH (Public Key Hash) oder 40 Hex Zeichen z.B.\r\n\t\t\/\/ 35c2fccec44bb363c62442c2a7f1fc9600893c30\r\n\t\tSystem.out.println(\"Public Key Hash (PKH, 20 Byte):    \" + Transform.bytesToHex(pkh));\r\n\t}\r\n}\r\n<\/pre>\n<p>Hier der Output:<\/p>\n<pre class=\"lang:default decode:true \" >Public Key (von Bitcoin 33 Byte) zum PKH (public Key Hash 20 Byte) transformieren:\r\n\r\nPublic Key (33 Byte):              02cbfb29329885196dd6c0d815e7279d019a9034da7423aab211bb58e1eb69ffc8\r\n1. SHA-256 Hash erzeugen\r\nSHA-256 Hash (32 Byte):            2eea7e9a811cdf4cc09da63aa24a5e27972a9792cc3d28bf724d99d2f3a099a4\r\n2. RIPEMD-160 Hash erzeugen\r\nPublic Key Hash (PKH, 20 Byte):    982a7da6c35c59f1f1e8ee64d05ecab26fdfcdcb<\/pre>\n<p>Man kann also gut sehen, das zumindestens 13 Byte eingespart wurden. Der ganze Code liegt auch in meinem  <a href=\"https:\/\/bitbucket.org\/itberater\/twhash\/src\/master\/\">Bitbucket-Repo<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der public Key wird zun\u00e4chst mit SHA-256 gehasht. Der Output dieser kryptografischen Hashfunktion wird dann mit RIPEMD-160 gehasht, einer anderen kryptografischen Hashfunktion, die als Output eine 160 Bit (20 Byte) lange Zahl erzeugt. Wir nennen diesen letzten Hash den public Key Hash (PKH). Wie hier im BPMN Flow dargestellt: &#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[220,1430,5,3897,79,1319],"tags":[1183,1012,4624,4628,4629,4623,4622,4630,176],"class_list":["post-16312","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-bpmn","category-java","category-java-programmierung","category-programmierung","category-sicherheit-2","tag-bitcoin","tag-hash","tag-hashen","tag-pkh","tag-public-key-hash","tag-ripemd-160","tag-ripemd160","tag-sha256","tag-sicherheit"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/16312","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=16312"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/16312\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16312"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16312"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16312"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}