3

im trying to convert a hash to a big integer so i can do some calculations with it. Im successful in that but on the other side i need to be able to convert the big integer back to the hash to do verification. But i cant do the conversion back succesfully, below is my code and the output. Please do advise and assist..

This is the code

//convert hash to bytes then to big int to mod pow
BigInteger hashy = new 
BigInteger(hash.getBytes(StandardCharsets.ISO_8859_1));
System.out.println("hashy: " +hashy);
//test if convert back to big int works
String convertedBackHash = (hashy.toByteArray()).toString();                
System.out.println("hash to hashy to hash: " + convertedBackHash);

This is the output

hash: d1bb961ac85f6d9ae66b469b5cabe83f9f88e4ee
hashy: 835979497806227327262557895525398820611883198135120938003873334575862278693562754177889725605221
hash to hashy to hash: [B@60e53b93

Anyone knows what went wrong?

2 Answers2

0
String convertedBackHash = (hashy.toByteArray()).toString();                

You are using Array#toString method which represents array object in hex format.

If you want to convert your bytes to string

String result = new String(hashy.toByteArray());  
System.out.println("hash to hashy to hash: " + result);
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • Thanks your method worked! But do you mind explaining why my method didnt work? Because from my point of view isnt my steps same as you? I did a conversion to a byte array from my big integer, and then used a .toString() on the byte array. But as for yours, you created a new String containing the byte array of the big integer? isnt is the same generally? please advice – user6235245 Nov 15 '17 at 09:05
  • Look at your `[B@60e53b93` You are using the wrong `toString()` method. You are getting the hex address in memory `@` of your binary array `B`. – rossum Nov 15 '17 at 09:36
  • This directly solves the issue that the hash string doesn't print correctly, but it doesn't handle the issue that the hash is still in hexadecimal format, and it doesn't handle zero padding issues which may result in a hash string that is either too large or too small. – Maarten Bodewes Nov 15 '17 at 22:12
  • He is *not* using `Array.toString()`, and it does *not* 'represent array object in hex format'. He is using `byte[].toString()`, which is inherited from `Object.toString()`, which returns the class of the object followed by its `hashCode()` in hex. – user207421 Nov 15 '17 at 22:27
  • @EJP That's what's wrong in the question, I was commenting on the answer. Read my answer to understand what I am talking about. It doesn't make sense to convert the hexadecimals to ASCII and then to an integer. That there are issues converting it back is of course also an issue, but I don't think it is the main one. – Maarten Bodewes Nov 15 '17 at 22:43
0

For cryptographic functions you generally need to convert the byte array (the hash) to a positive integer and back. This can be done by thinking of the byte array as a constant sized, unsigned, big endian integer.

PKCS#1 specifies this for RSA calculations, for instance, where OS2IP (octet string to integer primitive) converts from a byte array to an integer and I2OSP (integer to octet string primitive) converts back from the integer to an octet string. An octet string is nothing more than a byte array. Neither is particularly tricky to implement, but the fact that Java hasn't got the function build in (hint!) and that Java cannot resize arrays makes I2OSP more tricky than you might expect. Fortunately I already supplied the answer here - it took me some time to find it again.

Now your input hash seems to be hex encoded. This is not what you would want to turn into an integer. You want to turn the bytes represented by the byte array into an integer. So you first need to hex decode the bytes. There are plenty of libraries that implement hex encoding and there are answers here on Stackoverflow as well. Conversely, after I2OSP you want to encode the bytes back to hexadecimals if you want to view them. This way you only have to deal with an integer of half the size as well.

So BigInteger i = os2ip(Hex.decode(hashString)), then do stuff with i and when you've got it back again, String hashString = Hex.encodeToString(i2osp(i)).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thank you Maarten for going in so indepth to answer the question. This really helps. Thanks to Suresh also for trying to solve the problem! Thumbs up to both of you!!!! – user6235245 Nov 16 '17 at 06:00