What "SecretKeyFactory not available" does mean?
Solution 1
This is a verified java bug. See https://bugs.openjdk.java.net/browse/JDK-7022467
EDIT: Different java versions support different algorithms, you can also extend it with custom providers and so on. Oracle has a list for java 6 here http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html . For KeyFactory this is DSA.
Solution 2
You don't really need to use SecretKeyFactory
. You can create an AES key with the following;
byte[] keyData = ........
SecretKeySpec key = new SecretKeySpec(keyData, "AES");
If you want to do password based encryption (PBE) then simply choose a secure hashing algorithm that gives you a hash the same size as the required key. For example, if you want a 256 bit key for AES, here is a method to build the key;
private Key buildKey(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest digester = MessageDigest.getInstance("SHA-256");
digester.update(password.getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec spec = new SecretKeySpec(key, "AES");
return spec;
}
Edit:
I would recommend against using MD5 and DES unless this is a play project, both have weaknesses and are considered obsolete.
Solution 3
Not all versions of Java provide a SecretKeyFactory
for "AES" in their default providers.
If you want to generate a new key, choose the desired number of bits (128, 192, or 256) from a SecureRandom
instance, and use that random number to initialize a SecretKeySpec
instance.
If you are using password-based encryption, create a SecretKeyFactory
for the "PBKDF2WithHmacSHA1" algorithm, and use it to initialize a SecretKeySpec
instance as illustrated here.
yegor256
Lab director at Huawei, co-founder at Zerocracy, blogger at yegor256.com, author of Elegant Objects book; architect of Zold.
Updated on July 22, 2022Comments
-
yegor256 almost 2 years
What's wrong with this?
for (Object obj : java.security.Security.getAlgorithms("Cipher")) { System.out.println(obj); } javax.crypto.SecretKeyFactory.getInstance("AES");
This is the output (JDK 1.6 on Mac OS 10.6):
BLOWFISH ARCFOUR PBEWITHMD5ANDDES RC2 RSA PBEWITHMD5ANDTRIPLEDES PBEWITHSHA1ANDDESEDE DESEDE AESWRAP AES DES DESEDEWRAP PBEWITHSHA1ANDRC2_40 java.security.NoSuchAlgorithmException: AES SecretKeyFactory not available at javax.crypto.SecretKeyFactory.<init>(DashoA13*..) at javax.crypto.SecretKeyFactory.getInstance(DashoA13*..) ...
-
yegor256 over 12 yearsI'm getting the same exception for almost all algorithms from the list (only
DES
works). -
brady almost 12 yearsSimply hashing the password is not a secure way to derive a password. Use a recognized key derivation algorithm (also provided by JCA) to convert text to a secret key.
-
Tom about 11 years@erickson But the final 'evaluation' of the relevant issue (linked in the answer below) suggests to me that the above solution is the recommended solution for AES. How could we improve the above solution, without going back to SecretKeyFactory which is not going to support AES.
-
brady about 11 years@tom The final evaluation doesn't suggest using a single round of hashing to perform password-based encryption. Please see my answer for safely following the evaluation's guidance.
-
Tom over 10 yearsBe careful about that combination - big android bug fixed in 4.4 means that pre & post 4.4 produce different results. android-developers.blogspot.ca/2013/12/…
-
brady over 10 yearsDon't be careful with PBKDF2WithHmacSHA1; it's the algorithm you should use, and decrypts messages encrypted with SunJCE. If you have to work with data that was encrypted using the old, buggy version of Android, then you'll have to be aware of the non-standard 8bit algorithm. If you are using SunJCE to decrypt messages encrypted with buggy Android implementations, you'll need to set the upper 8 bits of each
char
in the password to zero yourself, as it doesn't provide an algorithm with this behavior. -
Tom over 10 yearsI didn't say don't use it - I just said to take care, and since there is an issue with Android (and BouncyCastle too, I believe) I don't think that is unwarranted.
-
brady over 10 yearsThat makes sense. I'm stressing the point because the leading answer has a horrible security flaw, simply using a hash function to derive a key.
-
VGR over 2 yearsThat bug is now at bugs.openjdk.java.net/browse/JDK-7022467. The original is viewable at web.archive.org/web/20130430082811/http://bugs.sun.com/….
-
jontro over 2 years@VGR feel free to edit the answer!