3

I'm currently working on an key-handling class in Java, specifically using a KeyStore. I'm trying to generate a SecretKey with an AES instance, then place it inside of the KeyStore using the setEntry() method.

I've included the relevant sections of my code:

// The KS Object
private KeyStore keyStore;

private KeyStore.SecretKeyEntry secretKeyEntry;
private KeyStore.ProtectionParameter protectionParameter;

private KeyGenerator keyGenerator;
private SecretKey secretKey, newSecretKey;


keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);

newSecretKey = keyGenerator.generateKey();

protectionParameter = new KeyStore.PasswordProtection(KEYSTORE_PASSWORD.toCharArray());
secretKeyEntry = new KeyStore.SecretKeyEntry(newSecretKey);

keyStore.setEntry(KEYSTORE_ALIAS, secretKeyEntry, protectionParameter);

The two constants I've used are defined as Strings, too.

The Exception I keep getting is in my setEntry() call:

java.security.KeyStoreException: Cannot store non-PrivateKeys
at sun.security.provider.JavaKeyStore.engineSetKeyEntry(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineSetKeyEntry(Unknown Source)
at java.security.KeyStoreSpi.engineSetEntry(Unknown Source)
at java.security.KeyStore.setEntry(Unknown Source)

I'm using mainly this document http://docs.oracle.com/javase/7/docs/api/java/security/KeyStore.html as a reference, along with some other sources.

Thanks in advance for any help.

5
  • So I presume you are using a Java 7 runtime environment? Could you print out the precise version? Have you installed the unlimited crypto policy files? Commented Aug 15, 2013 at 0:10
  • How did you initialize (load) the key store? I've retrieved the same exception, but I did have to insert a specific method to load the KeyStore instance. Commented Aug 15, 2013 at 0:31
  • I loaded the KeyStore using a FIS or a null parameter on the .load( , KEYSTORE_PASSWORD.toCharArray()) method. Commented Aug 15, 2013 at 0:54
  • After fiddling on with the code and more searching, I changed the instance of the KS I was using from (KeyStore.getDefaultType()) to simply ("JCEKS"). This appears to have solved the problem. Commented Aug 15, 2013 at 0:55
  • See my answer :). Note that your question is more to the point, so I would not call this a dupe. Commented Aug 15, 2013 at 1:09

1 Answer 1

10

I found this as a non-accepted answer on stackoverflow:

The "Cannot store non-PrivateKeys" error message usually indicates you are trying to use secret symmetric keys with a JKS keystore type. The JKS keystore type only supports asymmetric (public/private) keys. You would have to create a new keystore of type JCEKS to support secret keys.

It is very hard to confirm this, although my memory tells me it is correct.

Sign up to request clarification or add additional context in comments.

4 Comments

If you follow my solution and get an instance of a JCEKS KeyStore, it should work. The oracle example I was working from was misleading as they skipped this part out for Secret/Private Keys.
If anyone finds this using the "AndroidKeyStore" introduced in Android 4.3 it's the same deal, symmetric keys (i.e AES) are not supported Asymmetric only.
@scottyab Thanks - that's exactly the problem I'm seeing.
Note that Java 9 will switch to the PKCS#12 ("PKCS12") key store format by default. PKCS#12 key stores should allow SecretKey instances to be stored (and to be more secure to boot). This functionality should already be in Java 8 as well, but not as default. JCEKS could also be an option (as noticed in the comments below the question as well).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.