Matt Sheppard
Matt Sheppard

Reputation: 118053

Java equivalent of openssl blowfish decryption

I have a file of base64 encoded binary data provided by another system which I can decrypt successfully using the following openssl command line.

openssl enc -d -blowfish -a -in base64d_encrypted_content.txt

(Unfortunately about all I know about the encryption that's being applied)

In Java, how can I perform the same decryption?

Currently I have...

BufferedReader reader = new BufferedReader(new InputStreamReader(content.getInputStream()));
StringBuffer buffer = new StringBuffer();
String line = reader.readLine();
while (line != null) {
    buffer.append(line + "\n");
    line = reader.readLine();
}
reader.close();

BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(buffer.toString());

SecretKeySpec blowfishKey = new SecretKeySpec(password, "Blowfish");
Cipher blowfishCipher = Cipher.getInstance("Blowfish");
blowfishCipher.init(Cipher.DECRYPT_MODE, blowfishKey);
byte[] decryptedBytes = blowfishCipher.doFinal(decodedBytes);

but I get the following exception...

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.BlowfishCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

Upvotes: 2

Views: 1271

Answers (2)

rossum
rossum

Reputation: 15693

You have padding fault. What padding mode was used to encrypt the original cyphertext? You need to set the Java code to expect that form of padding.

If you don't know then try each of the allowed paddings in turn. Start with PKCS5/PKCS7 as it is probably the most common.

ETA

Your problem is probably not just padding. You need to be certain all elements are the same at both sides.

  • The key must be byte-for-byte identical.
  • The mode must be the same: CBC, CTR or ECB (ugh).
  • The IV must be the same, byte-for-byte.
  • The padding must be the same.

Don't rely on defaults, set all of them explicitly. With the key and IV, don't check characters, check bytes.

Upvotes: 1

Matt Sheppard
Matt Sheppard

Reputation: 118053

After a lot of searching around I ran across not-yet-commons-ssl which seems to provide a method replicating the openssl command line in Java...

byte[] decrypted = OpenSSL.decrypt("blowfish", password.toCharArray(), base64EncryptedBytes);

When I get some time I'll dig into their code and find out exactly what is being done. In the mean time it looks like OpenSSL.java is the place to start.

Upvotes: 2

Related Questions