0

I am trying to write a simple application that takes in uploaded files and encrypt them before storing them to disk.

here is a snippet

InputStream is = item.openStream(); // item is obtained from file upload iterator
try{
   PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(),  iterations, keyLength);
   SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); 
   SecretKey key = keyFactory.generateSecret(keySpec); // Throws Exception
   CipherInputStream cis;
   Cipher cipher = Cipher.getInstance("RSA");
   cis = new CipherInputStream(is, cipher);
   cipher.init(Cipher.ENCRYPT_MODE, key);
 } catch (Exception ex){
    // catches the following exceptopn 
    java.security.spec.InvalidKeySpecException: Inappropriate key specification
    at com.sun.crypto.provider.DESedeKeyFactory.engineGenerateSecret(DashoA13*..)
   //
 }

I also tried "RSA/ECB/PKCS1Padding " without success. What did I do wrong?

adaj21
  • 543
  • 3
  • 11
  • 25

1 Answers1

2

That is because you need to initialize a SecretKeyFactory that is compatible with the KeySpec you are providing it. Try this for example:

PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(),  iterations, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(key.getAlgorithm());
CipherInputStream cis = new CipherInputStream(is, cipher);
cipher.init(Cipher.ENCRYPT_MODE, key);

The SecretKeyFactory produced by this invocation can successfully generate a key from an instance of PBEKeySpec and the Cipher is initialized with the correct algorithm.

laz
  • 28,320
  • 5
  • 53
  • 50
  • Thanks @laz. I tried this and now it seems I have provider issue. Now the call to _Cipher.getInstance(key.getAlgorithm());_ throws "java.security.NoSuchAlgorithmException: Cannot find any provider supporting PBKDF2WithHmacSHA1". – adaj21 May 19 '12 at 12:37
  • @adaj21: You will have to tell us which Java platform you are using, and which version. – President James K. Polk May 19 '12 at 15:31
  • 1
    Oops, I put the wrong algorithm. I amended the answer with the correct one. – laz May 19 '12 at 15:53
  • @laz, thanks. I tried this and it works. How do I know which algorithm is supported? For example 3DES may not be strong enough for some applications. – adaj21 May 21 '12 at 10:36
  • @adaj21: Try [this page](http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html) for supported algoritms in the Sun/Oracle providers. – President James K. Polk May 21 '12 at 22:59
  • You can create a `SecretKey` from the encoded PBE Key as shown here: http://stackoverflow.com/a/992413/8753 – laz May 23 '12 at 01:57
  • @GregS, Thank you for the link. I must be doing something wrong. I have already found this page and tried the algorithms, the only one that worked was the 3DES. I intended in my previous question to ask how do I know which of the algorithms listed in this page are actually supported by the available provider? Do I need to download a special jar to have different algorithms, if so, from where? – adaj21 May 23 '12 at 19:14
  • @laz, I will follow the example of that page. How come my search did not hit it? I must learn how to google first :) – adaj21 May 23 '12 at 19:18
  • @adaj21: all those algorithms and all those providers are supported and available in Java SE 6 by default. However, the largest key sizes are only available if you install the unlimited cryptography jar files. – President James K. Polk May 23 '12 at 23:47