Wrong algorithm: Blowfish required
I'm hoping one of you can tell me why when attempting to decrypt an OpenSSL Blowfish encrypted file via the following code (below), the Blowfish Cipher initialization code yields:
java.security.InvalidKeyException: Wrong algorithm: Blowfish required
at com.sun.crypto.provider.SunJCE_u.a(DashoA13*..)
at com.sun.crypto.provider.SunJCE_k.a(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
at com.sun.crypto.provider.BlowfishCipher.engineInit(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at TestDecryption.main(TestDecryption.java:134)
/****************************************************************************/
/* */
/* @Copyright 2007 by Cast Iron Systems Corporation@*/
/* */
/* TestDecryption.java:*/
/*A program to test decryption of a previously encrypted file.*/
/* */
/****************************************************************************/
import java.io.FileInputStream;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.IvParameterSpec;
publicclass TestDecryption
{
//-
// Display usage of how to invoke this app/class:
//-
privatestaticvoid usage()
{
System.out.println("Usage: java TestDecryption encryptedFile password salt" );
System.out.println(" encryptedFile- The blowfish encrypted file." );
System.out.println(" password - The password/key for the encrypted file." );
System.out.println(" salt - The hex character salt string for password/key." );
return;
}
//-
// Convert a string of hex chars to a byte array:
//-
privatestaticbyte[] strToHex(String s)
{
int strLen = s.length();
if ((strLen % 2) != 0){
thrownew IllegalArgumentException("hex char string must be an even number of chars." );
}
byte[] hexBytes =newbyte[ strLen >> 1 ];
for (int i = 0; i < strLen; i+=2){
int highNibble = charToNibble( s.charAt(i) );
int lowNibble = charToNibble( s.charAt(i+1) );
hexBytes[i>>1] = (byte)((highNibble << 4) | lowNibble);
}
return hexBytes;
}
privatestaticint charToNibble(char c )
{
if (c >='0' && c <='9'){
return c -'0';
}
if (c >='a' && c <='f'){
return c -'a' + 0xa;
}
if (c >='A' && c <='F'){
return c -'A' + 0xa;
}
thrownew IllegalArgumentException("Invalid hex character: " + c );
}
// Algorithm for decrypting file content (Blowfish).
privatestaticfinal String decryptionAlgorithm ="Blowfish/CBC/PKCS5Padding";
publicstaticvoid main (String[] args)
{
//-
// Check/Validate input args ...
//-
// Ensure required args were supplied.
if (args.length != 3){
usage();
System.exit(-1);
}
// Required args:
String encryptedFile = args[0];// Complete path/name of encrypted file.
String password= args[1];// Password/key used to encrypt/decrypt the file.
String hexsalt= args[2];// Hex salt characters for password/key.
int requiredPasswordLength = 0;// Establish required length for password and salt args.
int requiredSaltLength= 0;
if (decryptionAlgorithm.startsWith("Blowfish" )){
requiredPasswordLength = 16;
requiredSaltLength= 16;
}elseif (decryptionAlgorithm.startsWith("DESede" )){
requiredPasswordLength = 24;
requiredSaltLength= 16;
}
if (password.length() != requiredPasswordLength){
System.out.println("password arg must be " + Integer.toString( requiredPasswordLength ) +" characters for this test: " + decryptionAlgorithm );
System.exit(-1);
}
if (hexsalt.length() != requiredSaltLength){
System.out.println("salt arg must be " + Integer.toString( requiredSaltLength ) +" characters for this test: " + decryptionAlgorithm );
System.exit(-1);
}
// Convert salt hex string to a hex byte array.
byte[] saltBytes =null;
try{
saltBytes = strToHex( hexsalt );
}catch (Exception e){
System.out.println( e.getMessage() );
System.exit(-1);
}
//-
// Read and decrypt specified file.
//-
try{
// Get/Load encrypted file content.
FileInputStream encryptedFileStream =new FileInputStream(encryptedFile);
int encryptedByteCount = encryptedFileStream.available();
byte[] encryptedData =newbyte[encryptedByteCount];
int bytesRead = encryptedFileStream.read(encryptedData, 0, encryptedByteCount);
encryptedFileStream.close();
if (bytesRead != encryptedByteCount){
thrownew Exception("Couldn't read encrypted file content" );
}
// Decrypt file content.
try{
String decryptionKey = password;
byte[] salt = saltBytes;
//PBEParameterSpec ps = new PBEParameterSpec( salt, 20 );
SecretKeySpec keySpec =new SecretKeySpec( decryptionKey.getBytes("UTF-8" ), decryptionAlgorithm );
Cipher decryptCipher = Cipher.getInstance( keySpec.getAlgorithm(),"SunJCE" );
//decryptCipher.init( Cipher.DECRYPT_MODE, keySpec, ps );
decryptCipher.init( Cipher.DECRYPT_MODE, keySpec,new IvParameterSpec( salt ) );
decryptCipher.doFinal( encryptedData );
}catch (Exception e){
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
}// main()
}// class TestDecryption

