Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Encryption/Decryption with Perl and Java

by jacques (Priest)
on May 25, 2006 at 01:40 UTC ( #551481=perlquestion: print w/replies, xml ) Need Help??
jacques has asked for the wisdom of the Perl Monks concerning the following question:

I need to encrypt a string in Java and decrypt it with Perl. I must use Crypt::CBC and the Blowfish algorithm (Crypt::Blowfish). I am using version 2.08 of C::CBC and 2.09 of C::Blowfish. For Java, I am using the default SUN JDK 1.4.2 crypto libraries (part of the standard VM).

I am having a very difficult time decrypting the string in Perl. I am not sure if the problem is with the Java, the Perl, or both. So I am presenting both programs below.

For the Java encryption, the IV is set to all 64-bit zero and the padding is PKCS5Padding. Of course, I tried to match this on the Perl side. C::CBC defaults to PKCS5Padding and I set the IV to "\0\0\0\0\0\0\0\0".

The key is 64 random hexadecimal characters (0-9 and A-F). I think the handling of the key in the Java code could be the cause of the problem, but I am not sure. The Java program prints the encrypted string to the screen, I then copy and paste it to the Perl script, so I can try to decrypt it. (That is how I am testing it.) Here is my Perl code:

my $key = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603D4022C031FAEE +D5C40"; my $vector = "\0\0\0\0\0\0\0\0"; my $cipher = Crypt::CBC->new({ 'key' => $key, 'iv' => $vector, 'prepend_iv' => 0, 'cipher' => 'Blowfish', }); my $plaintext = $cipher->decrypt($encrypted);
Here is the Java code:
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import; public class CryptoMain { public static void main(String[] args) throws Exception { String mode = "Blowfish/CBC/PKCS5Padding"; String algorithm = "Blowfish"; String secretStr = "8326554161EB30EFBC6BF34CC3C832E7CF8135C1999603 +D4022C031FAEED5C40"; byte secret[] = fromString(secretStr); Cipher encCipher = null; Cipher decCipher = null; byte[] encoded = null; byte[] decoded = null; encCipher = Cipher.getInstance(mode); decCipher = Cipher.getInstance(mode); Key key = new SecretKeySpec(secret, algorithm); byte[] ivBytes = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00 }; IvParameterSpec iv = new IvParameterSpec(ivBytes); encCipher.init(Cipher.ENCRYPT_MODE, key, iv); decCipher.init(Cipher.DECRYPT_MODE, key, iv); encoded = encCipher.doFinal(new byte[] {1, 2, 3, 4, 5}); // THIS IS THE ENCODED STRING I USE IN THE PERL SCRIPT System.out.println("encoded: " + toString(encoded)); decoded = decCipher.doFinal(encoded); System.out.println("decoded: " + toString(decoded)); encoded = encCipher.doFinal(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}); System.out.println("encoded: " + toString(encoded)); decoded = decCipher.doFinal(encoded); System.out.println("decoded: " + toString(decoded)); } ///////// some hex utilities below.... private static final char[] hexDigits = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; /** * Returns a string of hexadecimal digits from a byte array. Each * byte is converted to 2 hex symbols. * <p> * If offset and length are omitted, the complete array is used. */ public static String toString(byte[] ba, int offset, int length) { char[] buf = new char[length * 2]; int j = 0; int k; for (int i = offset; i < offset + length; i++) { k = ba[i]; buf[j++] = hexDigits[(k >>> 4) & 0x0F]; buf[j++] = hexDigits[ k & 0x0F]; } return new String(buf); } public static String toString(byte[] ba) { return toString(ba, 0, ba.length); } /** * Returns the number from 0 to 15 corresponding to the hex digit <i +>ch</i>. */ private static int fromDigit(char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; throw new IllegalArgumentException("invalid hex digit '" + ch + "' +"); }

Replies are listed 'Best First'.
Re: Encryption/Decryption with Perl and Java
by sgifford (Prior) on May 25, 2006 at 05:35 UTC
    One guess: it looks like your key is a hex string, and your Java program is converting it to binary, while your Perl program isn't.

    If I were debugging this, the next step I'd try is seeing if you can decrypt the string in Java, and encrypt the string in Perl. If both languages can, on their own, encrypt and decrypt the string, that's a good start. Now, if they both produce the same ciphertext, their encryption probably works and their decryption is broken; if they don't, their encryption is most likely broken.

    Probably in the process of puzzling through that you'll get the insight you need to find the bug; if not at least it will let you narrow down the source of the problem.

    Good luck!

Re: Encryption/Decryption with Perl and Java
by roboticus (Chancellor) on May 25, 2006 at 10:30 UTC

    I'll second sgifford's suggestion: First round-trip the encryption in one language. Then write the encryptor (or decryptor) in the other language and debug until you get the same output for the same input with both versions. Once you've debugged that, then you can encrypt the other half of the pair in the other language.

    One additional thing I'll suggest: If you look up papers on the web for the encryption scheme you're interested in, you'll often find examples of plaintext, key and encrypted text. Using those examples you can (a) find your bugs more easily, and (b) ensure that you don't accidentally "debug" the wrong side of things. (I've done that before: My "debugged" version would encrypt and decrypt, but there was a bug that seriously compromised the integrity of the encoding scheme. Had I bothered to compare my encrypted text to the version in the paper, I'd've found the bug much sooner. Then maybe the junk version wouldn't have made it into production..... Blecch!)


Re: Encryption/Decryption with Perl and Java
by exussum0 (Vicar) on May 25, 2006 at 14:33 UTC
    Just a note:
    byte[] b = (new BigInteger("98a7ba97b8a",16)).toByteArray()
    accomplishes the same thing in your java function there.
      Were you able to encrypt in perl and decrypt in java? pls share the solution. We really need this immediately.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://551481]
Approved by Zaxo
Front-paged by Tanktalus
[shmem]: trying to build a RPM for some perl with a bunch of modules. Trying perlbrew, trying alien.
[stevieb]: finally got my 12v solar setup for my Pi/Arduino, with a 12v 7.2Ah battery. Testing how long the Pi will run on the fully charged battery before I hook it up to the solar regulator. I expect between 8 and 18 hours, depending on load.
[shmem]: ...writing a Makefile for that. Edit, test, lather, rinse, repeat.

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2017-03-25 22:19 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (313 votes). Check out past polls.