TripleDES fails
All,
I have the following problem with encryption:
I want to encrypt String into byte[] using: PBEWithSHA1AndTripleDES
Here's the code:
publicclass SecurityTest{
//private static final String encodingType = "PBEWithSHA1AndTripleDES";
privatestaticfinal String encodingType ="PBEWithSHA1andDES";
/**
* @param args
*/
publicstaticvoid main(String[] args){
try{
char[] key ="12345678".toCharArray();
byte[] msg ="testmessage".getBytes();
KeySpec keySpec =new PBEKeySpec(key);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(encodingType);
SecretKey skey = secretKeyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(encodingType);
cipher.init(Cipher.ENCRYPT_MODE, skey);
byte[] result = cipher.doFinal(msg);
System.out.println(new String(result));
}catch (Exception e){
e.printStackTrace();
}
}
}
Coding with PBEWithSHA1andDES works fine but when I change it ot TripleDES one I got the following:
java.security.InvalidKeyException: Illegal key size ordefault parameters
at javax.crypto.Cipher.a(Unknown Source)
at javax.crypto.Cipher.a(Unknown Source)
at javax.crypto.Cipher.a(Unknown Source)
at javax.crypto.Cipher.init(Unknown Source)
at javax.crypto.Cipher.init(Unknown Source)
at com.collation.platform.security.auth.SecurityTest.main(SecurityProviderTest.java:25)
I read some stuff on this exception and I have the required jars (policy ones), so that is not a problem.
Any ideas anyone?
OK tried that:
public static void main(String[] args) {
try {
byte[] salt = new byte[8];
new Random().nextBytes(salt);
PBEParameterSpec params = new PBEParameterSpec(salt,512);
char[] key = new char[]{'H','a','r','d','S','h','i','t','D','e','e','p','S','h','i','t','H','o','l','y','S','h','i','t'};
byte[] msg = "testmessage".getBytes();
KeySpec keySpec = new PBEKeySpec(key);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(encodingType);
SecretKey skey = secretKeyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(encodingType);
cipher.init(Cipher.ENCRYPT_MODE, skey,params);
byte[] result = cipher.doFinal(msg);
System.out.println(new String(result));
} catch (Exception e){
e.printStackTrace();
}
}
with same result :(
Also I have read that TripleDES uses 192-bit key so I tried it. (Scuse my french) and still the same effert.
DES works TrilpeDES fails :(
How long salt and how many iterations do you use?
My simple PBE test harness
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.security.spec.*;
import sun.misc.*;
import java.util.*;
public class PBEEncryptDataString
{
static public class EncryptionException extends Exception
{
private EncryptionException(String text, Exception chain)
{
super(text, chain);
}
}
public PBEEncryptDataString(String algorithm, String provider, String passphrase, byte[] salt, int iterationCount, String characterEncoding) throws EncryptionException
{
if ((passphrase == null) || (passphrase.length() <= 6))
throw new IllegalArgumentException("The passphrase must be at least 6 characters");
if (salt == null)
throw new IllegalArgumentException("The salt cannot be 'null'");
if (iterationCount < 10)
throw new IllegalArgumentException("The iteration count must be greater than 10");
try
{
PBEParameterSpec params = new PBEParameterSpec(salt, iterationCount);
KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
SecretKey key = SecretKeyFactory.getInstance(algorithm, provider).generateSecret(keySpec);
this.characterEncoding = characterEncoding;
this.encryptCipher = Cipher.getInstance(algorithm, provider);
this.encryptCipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, params);
this.decryptCipher = Cipher.getInstance(algorithm, provider);
this.decryptCipher.init(javax.crypto.Cipher.DECRYPT_MODE, key, params);
}
catch (Exception e)
{
throw new EncryptionException("Problem constucting " + this.getClass().getName(), e);
}
}
synchronized public byte[] encrypt(String dataString) throws EncryptionException
{
assert dataString != null;
try
{
byte[] dataStringBytes = dataString.getBytes(characterEncoding);
byte[] encryptedDataStringBytes = this.encryptCipher.doFinal(dataStringBytes);
return encryptedDataStringBytes;
}
catch (Exception e)
{
throw new EncryptionException("Problem encrypting string", e);
}
}
synchronized public String decrypt(byte[] encryptedDataStringBytes) throws EncryptionException
{
assert encryptedDataStringBytes != null;
try
{
byte[] dataStringBytes = this.decryptCipher.doFinal(encryptedDataStringBytes);
String recoveredDataString = new String(dataStringBytes, characterEncoding);
return recoveredDataString;
}
catch (Exception e)
{
throw new EncryptionException("Problem decrypting string", e);
}
}
private final String characterEncoding;
private final Cipher encryptCipher;
private final Cipher decryptCipher;
public static void main(String[] args) throws Exception
{
final byte[] salt = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,};// 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, };
final String passphrase = "The Passphrase - make if fairly long so that there is lots and lots of entropy";
final int iterationCount = 31;
for (Provider provider : java.security.Security.getProviders())
{
Set<String> algs = new HashSet<String>();
System.out.println("Provider : " + provider.getName());
for (Enumeration en = provider.propertyNames(); en.hasMoreElements();)
{
String alg = (String)en.nextElement();
if (alg.matches("(?i)cipher.*?pbe.*?DES.*"))
{
alg = alg.replaceFirst("(?i).*?(?=pbe)", "");
if (!algs.contains(alg))
{
algs.add(alg);
System.out.println("" + alg);
PBEEncryptDataString pbeEncryptAgent = new PBEEncryptDataString(alg, provider.getName(), passphrase, salt, iterationCount, "UTF-8");
// Get the dataString to encrypt from the command line
String dataString = (args.length == 0)? "The quick brown fox jumps over the lazy dog." : args[0];
System.out.println("\tData string ....................[" + dataString + "]");
// Encrypt the data
byte[] encryptedDataStringBytes = pbeEncryptAgent.encrypt(dataString);
BASE64Encoder base64Encoder = new BASE64Encoder();
System.out.println("\tEncoded encrypted data string ..[" + base64Encoder.encode(encryptedDataStringBytes) + "]");
// Decrypt the data
String recoveredDataString = pbeEncryptAgent.decrypt(encryptedDataStringBytes);
System.out.println("\tRecovered data string ..........[" + recoveredDataString + "]");
}
}
}
}
}
}