15

I need to generate an SHA-256 checksum from a string that will be sent as a get param.

If found this link to generate the checksum.

Genrating the checksum like so:

  val digest = MessageDigest.getInstance("SHA-256");      
  private def getCheckSum() = {
    println(new String(digest.digest(("Some String").getBytes(StandardCharsets.UTF_8))))        
  }

prints checksum similar to this:

*║┼¼┬]9AòdJb:#↓o6↓T╞B5C♀¼O~╟╙àÿG

The API that we need to send this to says the checksum should look like this:

45e00158bc8454049b7208e76670466d49a5dfb2db4196

What am I doing wrong?

Please advise. Thanks.

1
  • 1
    She message digest will return raw bytes. You expected format requires them to be encoded as hex Commented Sep 20, 2017 at 19:08

4 Answers 4

27

Equivalent, but a bit more efficient:

MessageDigest.getInstance("SHA-256")
  .digest("some string".getBytes("UTF-8"))
  .map("%02x".format(_)).mkString
Sign up to request clarification or add additional context in comments.

3 Comments

Hash code generated using your mehtod doesnt seem to be equivalent to what is generated using the method from previous answer: imgur.com/a/a3Gfv
Yeah, sorry about that. Fixed now.
@Regressor that's a Sting.format instruction. x means hexademical, 02 means two digits, padded with 0 if necessary. So, say, 10 (a in hex) is printed as "0a", and 255 (ff) is "ff"
13

java.security.MessageDigest#digest gives a byte array.

scala> import java.security.MessageDigest
scala> import java.math.BigInteger

scala> MessageDigest.getInstance("SHA-256").digest("some string".getBytes("UTF-8"))
res1: Array[Byte] = Array(97, -48, 52, 71, 49, 2, -41, -38, -61, 5, -112, 39, 112, 71, 31, -43, 15, 76, 91, 38, -10, -125, 26, 86, -35, -112, -75, 24, 75, 60, 48, -4)

To create the hex, use String.format,

scala> val hash = String.format("%064x", new BigInteger(1, MessageDigest.getInstance("SHA-256").digest("some string".getBytes("UTF-8"))))
hash: String = 61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc

You can verify hash with command line tool in linux, unix

$ echo -n "some string" | openssl dgst -sha256
61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc

2 Comments

Small bug here, string representation is missing leading 0's, for example string 39 will return b918943df0962bc7a1824c0555a389347b4febdc7cf9d1254406d80ce44e3f9 instead of 0b918943df0962bc7a1824c0555a389347b4febdc7cf9d1254406d80ce44e3f9
Seems like you meant to use "%064x" instead of "%032x", that should solve the padding so you don't need padTo
1

Can use DatatypeConverter.printHexBinary.

Something like:

DatatypeConverter.printHexBinary(
  MessageDigest
    .getInstance(algorithm)
    .digest("some string").getBytes("UTF-8")))

Comments

0

Since jdk 17, we can use java.util.HexFormat

import java.security.MessageDigest
import java.util.HexFormat

val bytes = MessageDigest.getInstance("SHA-256")
  .digest("any string".getBytes("UTF-8"))

val sha256 =  HexFormat.of().formatHex(bytes)
// 1e57a452a094728c291bc42bf2bc7eb8d9fd8844d1369da2bf728588b46c4e75

val another = HexFormat.ofDelimiter(":").withUpperCase().formatHex(bytes)
// 1E:57:A4:52:A0:94:72:8C:29:1B:C4:2B:F2:BC:7E:B8:D9:FD:88:44:D1:36:9D:A2:BF:72:85:88:B4:6C:4E:75

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.