Search code examples
javascalashellbouncycastlesha

Unable to get matching SHA1 digest from bouncycastle and openssl dgst


Am i going crazy? Here's my scala code with "org.bouncycastle" % "bcprov-jdk15on" % "1.59"

import java.util.Base64
import java.security.MessageDigest
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.security.Security
import java.nio.charset.Charset

Security.addProvider(new BouncyCastleProvider)
val sha1 = MessageDigest.getInstance("SHA1", "BC")
val digest = sha1.digest("foo".getBytes(Charset.forName("UTF-8")))

Base64.getEncoder.encodeToString(digest)

this produces, for foo input C+7Hteo/D9vJXQ3UfzxbwnXaijM=

Openssl:

openssl dgst -binary -sha1 <<< "foo" | openssl enc -base64

for foo input 8dLS+STphqyG/fezbJS83zK+7BU=

The same is happening for MD5 and SHA256 Obviously someone is doing something different than the other.. but what?

I verified base64 encoding in isolation between openssl enc -base64 and java.util.Base64, and it seems like there's an extra character(..) in the openssl output, plus java.util.Base64 pads, otherwise it's a match

scala> Base64.getEncoder.encodeToString("foo,bar,etc".getBytes(Charset.forName("UTF-8")))
res6: String = Zm9vLGJhcixldGM=

$ openssl enc -base64 <<< "foo,bar,etc"
Zm9vLGJhcixldGMK

Solution

  • That's because shell adds a newline to the end of <<< foo, so the string that openssl sees is not just "foo", but rather "foo\n".

    Try echo -n foo | openssl dgst -binary -sha1 | base64