I'm trying to build a tool to decrypt content in bash encrypted in a scala application:
But first, I've to succeed encoding the same message in both languages and make them equal:
Given the passphrase "0123456789abcdef"
(hex: "30313233343536373839616263646566" and byte[]:[48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102])
scala> import javax.crypto.Cipher
scala> import javax.crypto.spec.SecretKeySpec
scala> val cipher = Cipher.getInstance("Blowfish")
scala> cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec("0123456789abcdef".getBytes("utf-8"), "Blowfish"))
scala> javax.xml.bind.DatatypeConverter.printBase64Binary(cipher.doFinal("message".getBytes("utf-8")))
res7: String = K679Jz06jmc=
But I can't reproduce the same with openssl
in bash.
$ echo "message" | openssl enc -a -e -blowfish -nosalt -nopad -k "0123456789abcdef"
LJ3iFJ2/mYk=
$ echo "message" | openssl enc -a -e -blowfish -nosalt -nopad -k "30313233343536373839616263646566"
JkkJgYv3fQg=
Any hint? Thanks!
It would be more accurate to tag OpenSSL, which runs the same from any shell or no shell at all.
OpenSSL enc
by default does password-based encryption, with a key (plus IV) derivation similar to (but not exactly) PBKDF1. To encrypt with a key, not password, you need to use UPPERCASE -K
with hex, and you need to specify at least part of -iv
; on the other hand -nosalt
is useless.
Also the echo
command adds a newline to the data it echoes, and encryption of 'm e s s a g e NL' is entirely different from encryption of 'm e s s a g e'. Some OSes and shells, depending on whether the echo
you are using is builtin or external, have ways to omit the newline, but they aren't all the same. OTOH all POSIX systems support printf
, so:
$ printf %s message | openssl enc -blowfish -K 30313233343536373839616263646566 -iv 00 -a
K679Jz06jmc=
EDIT: Artjom is correct; Java/Scala (probably) defaults to ECB, which is a Bad Idea; you should specify /CBC
or /CTR
and padding. Unlike aventurin I see no reason you should force yourself into the straightjacket of /NoPadding
; Java /PKCS5Padding
is compatible with OpenSSL's default. For CBC or CTR you need to explicitly set the IV (with the third argument to Cipher.init
) to get a deterministic result -- and you must either set the IV, or retrieve the default random one, to produce a decryptable result, which people usually want. OpenSSL enc -blowfish
defaults to CBC, but it's clearer to explicitly state -bf-cbc
or -bf-ctr
. Or -bf-ecb
if you really want ECB, which as above is Unrecommended.