Difference in blowfish encryption between Perl and Java

We´re writing and application in both Java and Perl storing encrypted CBC Blowfish in the same database. Both will be encrypting and decrypting, so they need to be able to get the plain text that the other encrypted.

a) I went to some online tools to encrypt some text with CBC and IV vector. One such site is this plaintext HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU key 1234567890 since the site does not allow to enter the IV vector we assumed it would be zeroed which turned out to be right:

ciphertext P4mtWDzIIc2x/Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04+Tg0q7HpLalow0J6nZNUW+HWtRvYmLnt92UuIZ1ckaBEa9TSdR2YP9rQ==

b) The following Java code does the encryption:

import java.security.InvalidAlgorithmParameterException;  
import java.security.InvalidKeyException;  
import java.security.NoSuchAlgorithmException;  

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.*;

import org.apache.commons.codec.binary.*;

public class simple {

 public static void main(String[] args) {
   String Key = "1234567890";
   byte[] KeyData = Key.getBytes(); 
   String IV    = "\0\0\0\0\0\0\0\0";

   try { 
     SecretKeySpec KS = new SecretKeySpec(KeyData, "Blowfish");
     // modo CBC
     Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
     try {
       try {    
         IvParameterSpec IVparam = new javax.crypto.spec.IvParameterSpec(IV.getBytes());                     
         cipher.init(Cipher.ENCRYPT_MODE, KS,IVparam);
       } catch (InvalidAlgorithmParameterException e) {System.out.println(e);};  
     } catch (InvalidKeyException e) {System.out.println(e);};  

    // get the text to encrypt
    String inputText = "HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU";

    // encrypt message
    try {
      byte[] encrypted = cipher.doFinal(inputText.getBytes());
      Base64 b64 = new Base64();
      System.out.println("Java Ciphertext\n" + b64.encodeAsString(encrypted));
    } catch (IllegalBlockSizeException e) {System.out.println(e);}
    catch (BadPaddingException e) {System.out.println(e);}  
   }  
   catch (NoSuchPaddingException e) {}
   catch (NoSuchAlgorithmException e) {}
 }   

}

The output is: Java Ciphertext P4mtWDzIIc2x/Taqc9T46A3T0aTCelmANBRf6RgEzSF29DLdMRiEhck98jac04+Tg0q7HpLalow0J6nZNUW+HWtRvYmLnt92UuIZ1ckaBEaLkpDfHZfp8g==

As you can see both outputs are "almost" the same (Maybe due to padding but that's no relevant at the moment. It´s strange however since the plaintext is intentionally 80 caracters to avoid padding)

c) We wrote this small Perl program:

#!/usr/bin/perl -w
use strict;
use Crypt::Blowfish;
use MIME::Base64;
use Crypt::CBC;

my $cipher = Crypt::CBC->new(-key => "1234567890\0\0\0\0\0\0", -cipher => "Blowfish", -iv => "\0\0\0\0\0\0\0\0", -literal_key => 1, -header => "none", -keysize => 16);
my $ciphertext = $cipher->encrypt("HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU");

print "Perl Base64: ",encode_base64($ciphertext),"\n"; 
print "Descrifrado: ", $cipher->decrypt($ciphertext); 

But this program produce the following: Perl Base64: AW0AYJfIp1Lg5L+zTM0nZj07U6ETlxxIg3CKiZItg8wkA1Jqx79ZckzWfYwzN26ZPyCDnlfh0b37 0ZK61ng8MaMc9RFgtuXTeYLBOJC7LGYCHlMddmPwUQ== Descrifrado: HELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOUHELLOYOU

Which is not the same as the Java program (which is consistent with the online tools) although it can get the plain text correctly

So maybe we are not prompting the same parameters in the object creation. In particular:

my $cipher = Crypt::CBC->new(-key => "1234567890\0\0\0\0\0\0", -cipher => "Blowfish", -iv => "\0\0\0\0\0\0\0\0", -literal_key => 1, -header => "none", -keysize => 16);

After inspecting the code my only guess is that Java and Perl use different key size, so my question is

¿What key size does Java use? After browsing the source code for SecretKeySpec here we could not determine such size so 128 bits was assumed, hence the 16 size (16 x 8 = 128) and the \0 padding of the key in the Perl code.

Of course, If you can spot something else wrong, it would be greatly appreciated.

Answers


In Java, you use

String Key = "1234567890";

In Perl, you use

my $key = "1234567890\0\0\0\0\0\0";

If you actually used the same key, you'd get the same result.

my $key = "1234567890";

-literal_key => 1, -key => $key, -keysize => length($key)

Need Your Help

PLSQL Printing prime numbers

sql oracle plsql

I want to print prime numbers between 1 to 50. But I don't understand what I am doing wrong in my code. After BEGIN, SQLDeveloper says I had an error because it expected another sign and not = .

Silverlight: Binding a property of a resource object

silverlight data-binding resources

I'm trying to bind a property of a resource object to a control (a combo...) - the thing seems to work in the designer, but it is not working at runtime.