PBE encryption shows different output on IBMJCE and SunJCE providers

PBE encryption shows different output on IBMJCE and SunJCE providers - when I ran the following program on Sun JDK and IBM JDK, I got different results. Can anybody tell me the reason or give me a solution ?

import java.security.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.io.*;

public class PbeEncryption{

public static void main(String args[]) throws Exception{

String MYPBEALG = "PBEWithSHA1AndDESede" ;

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

String password = "password" ;

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());

SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

MYPBEALG = MYPBEALG + "/CBC/PKCS5PADDING";

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

byte[] abyte0 = pbeCipher.doFinal(password.getBytes());

String encoded = new String(abyte0, "UTF-8");

FileOutputStream fos = new FileOutputStream("encrypted.txt");

fos.write(abyte0);

fos.close();

System.out.println("********* E N C O D E D B Y T E S **********");

for(int i=0; i<abyte0.length;i++){

System.out.print((int)abyte0 + " ");

}

System.out.println("********************************************");

System.out.println("ENCRYPTION SUCCESSFULL .......");

}

}

Thanks in advance>

[1637 byte] By [Mkarattua] at [2007-10-2 23:50:35]
# 1

> byte[] abyte0 =

> = pbeCipher.doFinal(password.getBytes());

>

> String encoded = new String(abyte0, "UTF-8");

>

An example of just about the most common problem posted on this forum. This about as wrong as you can get. It is almost always wrong to convert arbitrary byte to a String, even with utf-8, because not all byte sequences create valid characters and it almost certainly will not be reversible.

If you must have a String version of encrypted bytes then use Base64 or Hex encoding.

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 2
I dont think encoding is the problem here.if so, atleast the following piece of code should show similar results on both platformsfor(int i=0; i<abyte0.length;i++){ System.out.print((int)abyte0 + " ");}>
Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 3

Plz consider this code...

I have removed encoding related snipplets from the code.

import java.security.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.io.*;

public class PbeEncryption{

public static void main(String args[]) throws Exception{

String MYPBEALG = "PBEWithSHA1AndDESede" ;

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

char[] pwd = {103 , 123 , 84 , 92 , 63 , 83 , 40 , 100};

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

PBEKeySpec pbeKeySpec = new PBEKeySpec(pwd);

SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

MYPBEALG = MYPBEALG + "/CBC/PKCS5PADDING";

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

byte[] abyte0 = pbeCipher.doFinal(new byte[]{103 , 23 , 84 , 92 , 23 , 83 , 10 , 100});

System.out.println("********* E N C O D E D B Y T E S **********");

for(int i=0; i<abyte0.length;i++){

System.out.print((int)abyte0 + " ");

}

System.out.println("********************************************");

}

}>

Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 4

> I dont think encoding is the problem here.

It may not be THE problem but it will be A problem.

>

> if so, atleast the following piece of code should

> show similar results on both platforms

>

> for(int i=0; i<abyte0.length;i++){

>System.out.print((int)abyte0 + " ");

Rather than looping yourself, use Arrays.toString(bByteArray) to do this.

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 5

I can run this on Sun JDK but until I can find out how to download the IBM unlimted strength policy files I cannot run it on IBM!

import java.util.*;

import javax.crypto.*;

import javax.crypto.spec.*;

public class PbeEncryption

{

public static void main(String args[]) throws Exception

{

String MYPBEALG = "PBEWithSHA1AndDESede" ;

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

char[] pwd = {103 , 123 , 84 , 92 , 63 , 83 , 40 , 100};

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

PBEKeySpec pbeKeySpec = new PBEKeySpec(pwd);

SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

MYPBEALG = MYPBEALG + "/CBC/PKCS5PADDING";

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

byte[] abyte0 = pbeCipher.doFinal(new byte[]{103 , 23 , 84 , 92 , 23 , 83 , 10 , 100});

System.out.println("********* E N C O D E D B Y T E S **********");

System.out.println(Arrays.toString(abyte0));

System.out.println("********************************************");

}

}

produces

********* E N C O D E D B Y T E S **********

[-48, 0, 75, -35, -18, 52, -121, -30, -7, -120, 11, 14, 23, -8, 40, -42]

********************************************

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 6

You can get unlimited jurisdiction policy files for IBM JDK

from the following site:

http://www.ibm.com/developerworks/java/jdk/security/index.html

(You need to register with IBM to download the policy files.)

Then-->

Click J2SE 5.0

Click IBM SDK Policy files

The Unrestricted JCE Policy files Web site is displayed.

Select Unrestricted JCE Policy files for SDK 1.4.2[this is same for java 1.5

also]

Then download Unrestricted JCE policy files for use with IBM's SDK for Java

1.4

unrestrict142.zip .

Extract this file and replace local_policy.jar and

US_export_policy.jar in the $JAVA_HOME/jre/lib/security

Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 7
I have installed the IBM unlimited files and it would seem that there is a mismatch between IBM and Sun. Looks like a bug report needs to be raised but I hav enot idea where!At some point I will try to compare IBM, Sun and BC PBE implementations.
sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 8

I have just established tha the key bytes are the same for both IBM and Sun so it has (almost certainly) to be a problem with the Ciperh and it's initialization.

Probably ignore the above since the key byes have only length 8 and not 16 or 24 as required by DESede!

Message was edited by:

sabre150

Short sighted of me! It gives the ASCII byters presented as the char array!

Message was edited by:

sabre150

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 9

I am now convinced you have a found a real problem. If I use MD5 rather than SHA1 then the two give the same results

Java vendor : IBM Corporation

Algorithm: PBEWithMD5AndTripleDES

class com.ibm.crypto.provider.PBEKey [103, 123, 84, 92, 63, 83, 40, 100]

********* E N C R Y P T E DB Y T E S **********

[-104, 58, -113, -77, 58, -8, -92, 82, 76, 44, 126, 90, 62, 34, 120, -73]

**************************************************

Java vendor : Sun Microsystems Inc.

Algorithm: PBEWithMD5AndTripleDES

class com.sun.crypto.provider.PBEKey [103, 123, 84, 92, 63, 83, 40, 100]

********* E N C R Y P T E DB Y T E S **********

[-104, 58, -113, -77, 58, -8, -92, 82, 76, 44, 126, 90, 62, 34, 120, -73]

**************************************************

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 10
Did u change anything otherthan Algorithm in the code? I am getting java.security.InvalidKeyException: Illegal key size on Sun JDK.
Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 11

> Did u change anything otherthan Algorithm in the

> code? I am getting java.security.InvalidKeyException:

> Illegal key size on Sun JDK.

Quite a bit of simplification (my view anyway)

import java.util.*;

import javax.crypto.*;

import javax.crypto.spec.*;

public class PbeEncryption

{

public static void main(String args[]) throws Exception

{

String MYPBEALG = "PBEWithMD5AndTripleDES" ;

System.out.println("Java vendor : " + System.getProperty("java.vendor"));

System.out.println("Algorithm: " + MYPBEALG);

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

char[] pwd = {103 , 123 , 84 , 92 , 63 , 83 , 40 , 100};

PBEKeySpec pbeKeySpec = new PBEKeySpec(pwd);

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

SecretKey pbeKey = SecretKeyFactory.getInstance(MYPBEALG).generateSecret(pbeKeySpec);

System.out.println(pbeKey.getClass() + " " + Arrays.toString(pbeKey.getEncoded()));

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

byte[] abyte0 = pbeCipher.doFinal(new byte[]{103 , 23 , 84 , 92 , 23 , 83 , 10 , 100});

System.out.println("********* E N C R Y P T E DB Y T E S **********");

System.out.println(Arrays.toString(abyte0));

System.out.println("**************************************************");

}

}

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 12
My requirement is to decrypt a file on IBM JDK which is encrypted on Sun JDK. I couldnt do it even with PBEWithMD5AndTripleDES, though both shows same output while encryption...
Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 13

> My requirement is to decrypt a file on IBM JDK which

> is encrypted on Sun JDK. I couldnt do it even with

> PBEWithMD5AndTripleDES, though both shows same output

> while encryption...

So what does your decryption code look like and how are you shipping teh encrypted data from the encrypting process to the decrypting process?

sabre150a at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 14

I write the encrypted bytes into a file and try to decrypt the file using IBM JDK.

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());

SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);

File file = new File("encrypted.txt");

byte[] toRead = new byte[(int)file.length()];

FileInputStream fis = new FileInputStream(file);

fis.read(toRead);

fis.close();

System.out.println("read =" + Arrays.toString(toRead));

byte[] abyte0 = pbeCipher.doFinal(toRead);

Mkarattua at 2007-7-14 16:36:02 > top of Java-index,Security,Cryptography...
# 15

I have not problem encryption with one an ddecryption with the other using algorithm "PBEWithMD5AndTripleDES".

I use this to encrypt for both IBM and Sun

import java.util.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.io.*;

public class PbeEncryption

{

public static void main(String args[]) throws Exception

{

String MYPBEALG = "PBEWithMD5AndTripleDES" ;

String dataToEncrypt = "The quick brown fox jumps over the lazy dog.";

System.out.println("Java vendor : " + System.getProperty("java.vendor"));

System.out.println("Algorithm: " + MYPBEALG);

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

char[] pwd = {103 , 123 , 84 , 92 , 63 , 83 , 40 , 100};

PBEKeySpec pbeKeySpec = new PBEKeySpec(pwd);

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

SecretKey pbeKey = SecretKeyFactory.getInstance(MYPBEALG).generateSecret(pbeKeySpec);

System.out.println(pbeKey.getClass() + " " + Arrays.toString(pbeKey.getEncoded()));

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

byte[] abyte0 = pbeCipher.doFinal(dataToEncrypt.getBytes("UTF-8"));

System.out.println("********* E N C R Y P T E DB Y T E S **********");

System.out.println(Arrays.toString(abyte0));

System.out.println("**************************************************");

DataOutputStream dostrm = new DataOutputStream(new FileOutputStream(System.getProperty("user.home") + "/zz"));

dostrm.writeShort(abyte0.length);

dostrm.write(abyte0);

dostrm.flush();

dostrm.close();

}

}

and this to decrypt using IBM or Sun

import java.util.*;

import javax.crypto.*;

import javax.crypto.spec.*;

import java.io.*;

public class PbeDecryption

{

public static void main(String args[]) throws Exception

{

String MYPBEALG = "PBEWithMD5AndTripleDES" ;

System.out.println("Java vendor : " + System.getProperty("java.vendor"));

System.out.println("Algorithm: " + MYPBEALG);

byte[] salt = new byte[] {103 , -73 , -94 , 12 , -73 , -33 , 1 , 109};

int count = 10;

char[] pwd = {103 , 123 , 84 , 92 , 63 , 83 , 40 , 100};

PBEKeySpec pbeKeySpec = new PBEKeySpec(pwd);

PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);

SecretKey pbeKey = SecretKeyFactory.getInstance(MYPBEALG).generateSecret(pbeKeySpec);

System.out.println(pbeKey.getClass() + " " + Arrays.toString(pbeKey.getEncoded()));

Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);

DataInputStream distrm = new DataInputStream(new FileInputStream(System.getProperty("user.home") + "/zz"));

int len = distrm.readShort();

byte[] encryptedBytes = new byte[len];

distrm.readFully(encryptedBytes);

distrm.close();

byte[] decryptedBytes = pbeCipher.doFinal(encryptedBytes);

System.out.println(new String(decryptedBytes,"UTF-8"));

}

}

Note that I do not convert encrypted data to Java Strings.

sabre150a at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...
# 16
Hi,PBEWithMD5AndTripleDES worked fine for me too...Plz let me know if you get any solution for the other algorithm..
Mkarattua at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...
# 17
Just a thought. Could it be that IBM and Sun are using different key lengths? Maybe one DES approach uses the same key for both DES encryption phases and the other uses a different key for each encryption phase.I don't see how to test this hypothesis.
sabre150a at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...
# 18

From SUN security team

The PKCS12 PBEWithSHA1AndDESede implementations between SunJCE and IBMJCE providers are interoperable. However, its name is not, i.e.

"PBEWithSHA1AndDESede" for SunJCE provider and

"PBEWithSHAAnd3KeyTripleDES" for IBMJCE provider.

Use:

String MYPBEALG = "PBEWithSHA1AndDESede" ;

try{

Provider[] providers = Security.getProviders("Cipher.OID.1.2.840.113549.1.12.1.3");

MYPBEALG = (String)providers[0].get("Alg.Alias.Cipher.OID.1.2.840.113549.1.12.1.3");

}catch(Exception e){}

Mkarattua at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...
# 19
See the solution here http://forum.java.sun.com/thread.jspa?threadID=749835&messageID=4320560#4320560
Mkarattua at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...
# 20
solution at http://forum.java.sun.com/thread.jspa?threadID=749835&messageID=4320560#4320560
Mkarattua at 2007-7-21 8:53:27 > top of Java-index,Security,Cryptography...