2

So I have been stuck for ages and am having trouble decrypting a file that I encrypted using PBEWithHmacSHA256AndAES_128.

The encryption works fine, but when trying to decrypt it, I get the following error:

Exception in thread "main"
java.security.InvalidAlgorithmParameterException: Wrong parameter type: PBE expected

The error is happening at this line:

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

Here is the encryption code I used:

// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(SALT, COUNT);
pbeKeySpec = new PBEKeySpec(get_SHA_1_SecurePassword(password, SALT).toCharArray());
keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// PRINT HASH OF PW  
System.out.println(get_SHA_1_SecurePassword(password, SALT).toCharArray());

// Create PBE Cipher and initialise PBE Cipher with key and parameters
Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

// Get bytes of input file
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);

// Encrypt and get bytes of encrypted file
byte[] iv = pbeCipher.getIV();
byte[] outputBytes = pbeCipher.doFinal(inputBytes);

String fileName = inputFile.getName();
File outputFile = new File(fileName + ".enc");
FileOutputStream outputStream = new FileOutputStream(outputFile);

// store first 16 bytes in the file as the IV
outputStream.write(iv);

// store the rest of the encrypted file
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();

return outputFile;

Here is the decryption I am trying to get working:

// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(SALT, COUNT);
pbeKeySpec = new PBEKeySpec(hashedReadPasswords[index].toCharArray());
keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");

SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");

// Get bytes of encrypted file
FileInputStream inputStream = new FileInputStream(encryptedFile);
byte[] inputBytes = new byte[(int)encryptedFile.length()];
inputStream.read(inputBytes);

// Get IV
byte[] iv = new byte[16];
for(int i=0; i<16; i++)
{
  iv[i] = inputBytes[i];
}

// Get encrypted data
byte[] cipherBytes = new byte[inputBytes.length-16];
int y=0;
for(int i=16; i<inputBytes.length; i++)
{
  cipherBytes[y] = inputBytes[i];
  y++;
}

// Initialise PBE Cipher with key and parameters
IvParameterSpec ivSpec = new IvParameterSpec(iv);
pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, ivSpec);

// decrypt and get bytes of plain text file
byte[] outputBytes = pbeCipher.doFinal(cipherBytes);

File outputFile = new File("decrypted_BS13");
FileOutputStream outputStream = new FileOutputStream(outputFile);

// store the rest of the decrypted file
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();

return outputFile;

Any help would be greatly appreciated, no matter what I find online - it's not helping!

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
chozenn300
  • 23
  • 3

2 Answers2

1

EDIT: Please see this blog for example PBE encryption and decryption code (although don't use the same ciphers that the blog is using because they are insecure!) that works.

You have a few problems here.

This is definitely wrong, although it is not causing the problem you are describing:

pbeKeySpec = new PBEKeySpec(hashedReadPasswords[index].toCharArray());

You need to provide the same password as was used to encrypt it. You cannot put in a hashed password to decrypt. So you need to pass in a similar pbeKeySpec as you used for encrypt.

PBE means "password based encryption". It is an algorithm for turning a password into an encryption key, in a secure way. This means that the key you decrypt with needs to be the same as the key you encrypt with, and derived the same way.

TheGreatContini
  • 6,429
  • 2
  • 27
  • 37
  • You're right I know that you shouldn't use the actual hash to encrypt, but I was trying to decrypt using the same exact hash (i used the same salt). Is there a way to get this working without using external libraries? I am only supposed to use the standard cryptography library that comes with java – chozenn300 May 14 '16 at 21:39
  • @chozenn300 I think the blog I referenced is using only Java, no external libraries. – TheGreatContini May 14 '16 at 21:52
0

This question is solved here: How do I properly use the "PBEWithHmacSHA512AndAES_256" algorithm?

Because the algorithm uses AES to cipher, you need the used IV to decipher. Although, you also need the PBE parameters (The error you are getting), so, to get the IvParameterSpec and PBEParameterSpec has one variable, you call pbeCipher.getParameters() that returns a AlgorithmParameters instance containing the IvParameterSpec and PBEParameterSpec used on the cipher.
Warning: you must call the method after the init

Cipher

Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
AlgorithmParameters params = pbeCipher.getParameters();

Decipher

pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, params);
Community
  • 1
  • 1