## Convert between String/Hex/Byte in Java for sha256 - wrong format?

2

0

I am trying to convert a bitcoin address and have the following code from here (Calculate Segwit address from public address, 2nd answer):

Step1: $printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt Step2:$ printf $( cat adr.txt | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) >adr.hex Step3:$ openssl dgst -sha256 -binary <adr.hex >tmp_sha256.hex
Step4: $openssl dgst -ripemd160 <tmp_sha256.hex ## result should be: 56379c7bcd6b41188854e74169f844e8676cf8b8  Now I want to do this in Java. I currently have the following code. No matter what I try, I dont get the correct result. :( String address = "1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9"; // step 1 System.out.println("address: " + address); String addressHex = toHex(address); System.out.println("address hex: " + addressHex); byte[] addressBytes = addressHex.getBytes(StandardCharsets.UTF_8); // step 2 MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(addressBytes); // step 3 RIPEMD160Digest digest2 = new RIPEMD160Digest(); // steps 4 digest2.update(hash, 0, hash.length); byte[] out = new byte[20]; digest2.doFinal(out, 0); System.out.println("result: " + bytesToHex(out)); // = 62ab42cba5d2632d1350fafb2587f5d2ece445d3 // should be 56379c7bcd6b41188854e74169f844e8676cf8b8  Output: address: 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 address hex: 314c383853323643356f796a4c31676b58734265597748486a764776436369647239 result: 62ab42cba5d2632d1350fafb2587f5d2ece445d3  Can someone help me? I think the problem is somewhere doing the conversion String/hex/byte ...? I tried really hard, but cannot find the correct way to do it. I also tried to convert the address to hex and after that to bytes, but doesnt work neither. :/ // updated post ... still doesnt show the correct result :/ // update2: byte[] address = ("1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9").getBytes(); System.out.println("address byte array: " + address); String addressHex = bytesToHex(address); System.out.println("address hex: " + addressHex); byte[] addressBytes = addressHex.getBytes(); MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(addressBytes); RIPEMD160Digest digest2 = new RIPEMD160Digest(); digest2.update(hash, 0, hash.length); byte[] out = new byte[20]; digest2.doFinal(out, 0); System.out.println("result: " + bytesToHex(out));  Output address byte array: [B@108c4c35 address hex: 314c383853323643356f796a4c31676b58734265597748486a764776436369647239 result: 62ab42cba5d2632d1350fafb2587f5d2ece445d3  Please read my answer in the original question you linked, the code you are trying to convert is wrong in the first place – MeshCollider – 2017-12-31T00:11:40.097 ## Answers 1 Ok, here is the plain code for conversion from legacy to segwit:  String addressToConvert = "1BGJEft81aaudqaCCcNnhsRQBA3Y96KYtx"; byte[] decoded = org.bitcoinj.core.Utils.parseAsHexOrBase58(addressToConvert); // We should throw off header byte that is 0 for Bitcoin (Main) byte[] pureBytes = new byte[20]; System.arraycopy(decoded, 1, pureBytes, 0, 20); // Than we should prepend the following bytes: byte[] scriptSig = new byte[pureBytes.length + 2]; scriptSig[0] = 0x00; scriptSig[1] = 0x14; System.arraycopy(pureBytes, 0, scriptSig, 2, pureBytes.length); byte[] addressBytes = org.bitcoinj.core.Utils.sha256hash160(scriptSig); // Here are the address bytes byte[] readyForAddress = new byte[addressBytes.length + 1 + 4]; // prepending p2sh header: readyForAddress[0] = (byte) 5; System.arraycopy(addressBytes, 0, readyForAddress, 1, addressBytes.length); // But we should also append check sum: byte[] checkSum = Sha256Hash.hashTwice(readyForAddress, 0, addressBytes.length + 1); System.arraycopy(checkSum, 0, readyForAddress, addressBytes.length + 1, 4); // To get the final address: String segwitAddress = Base58.encode(readyForAddress);  Functions (like org.bitcoinj.core.Utils.parseAsHexOrBase58) are taken from bitcoinJ library, as I mentioned earlier. The resulting address is 3G7YPGDLLeaf1R36wrVxnSAhWMaA81oNhJ. It can be checked here: Bip39 with mnemonic: "hood fatal cabbage proud lift amazing today mom disorder decorate eternal action punch finish drop thing chicken host erode bean rescue oblige mango double". To do that you should select "BIP49" and see the produced segwit address. Corresponding legacy address can be found at BIP32 tab, but you should manually insert derivation path m/49'/0'/0'/0. Note that private keys for them are equal: L38zkVFvLmVmHTpFdqfSP2WrQ1qcZnB829rthRS1rRexcc7RKuHr Your address 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 is converted to 39gGJc9HiemSJwpa2smXgCXMW8y9FNzFDe. How can I give you 10M upvotes? Thanks! Works perfectly! TY TY TY! – A.c – 2017-12-30T17:16:58.993 1 I have not the Java solution, but I can indicate the error. The conversion to hex is apparently missing. When I do the hash on the text file itself, I also get the wrong result: $ printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt
$openssl dgst -sha256 -binary <adr.txt >tmp_sha256.hex$ openssl dgst -ripemd160  <tmp_sha256.hex
(stdin)= db151e871af66b1323893e3f527e22f7684718af


so the transformation into a hex byte array "addressHex" is for sure missing something.

Update:

I can see the "bytesToHex()" function, was this the code from the link I provided in the other thread? If so, try to dump the output of your java into a file, and use hexdump to verify. So you can concentrate on these two lines (I made the sed command shorter, without "cat"):

$printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt$ printf $( sed 's/[[:xdigit:]]\{2\}/\\x&/g' adr.txt ) >adr.hex$ hexdump -C adr.hex
00000000  31 4c 88 53 26 c5 6f 79  6a 4c 31 67 6b 58 73 be  |1L.S&.oyjL1gkXs.|
00000010  59 77 48 48 6a 76 47 76  cc 69 64 72 39           |YwHHjvGv.idr9|
0000001d


Here you should receive the same result by your java code, then you'd be good to go :-)

Thanks, I edited my code but it still doesnt work. I have also edited my post to now show the new code. – A.c – 2017-12-30T11:05:31.833

see my update, that's so far all I can do ... – pebwindkraft – 2017-12-30T12:37:32.933

Please listen to my answer in the other thread, the approach is completely wrong from the start and you may end up losing funds if you use it. You should not be hashing the address at all – MeshCollider – 2017-12-31T00:10:44.877

1

Address is in Base58 format. So, if you want to fet hex representation, you should firstly convert base58-address string to byte array and then convert it to hex string. bitcoinJ library has utilities for that, you can find all of the conversions there.

Thanks! I tried to implement your suggestion but I am still not able to get the correct result. I updated my post ("update2"). ty! – A.c – 2017-12-30T12:20:53.877