James,

I’ve been investigating the same problem.  From my research the best
that appears to be possible is to provide a level of indirection in
hiding the key used for encryption.

The option I went with is storing the encryption key in a key store
file.  Now to get at the key one needs to know the location of the key
store, the key store’s password, the alias name for the stored
encrypted key, and possibly a second password on the key store entry.
This prevents the key from being seen in plain text in source code or
main configuration files such as web.xml.  Anyone with access to the
source for the web app can still reverse engineer the process and
extract the encryption key.  To make it a bit harder one could try to
spread around the key store name, its password, the alias, etc.
between configuration files and source code.  However nothing can be
made full proof.

I would be interested in hearing if anyone has come up with any other
strategies.

See below for code snippets for creating the key store and reading out
the key entry.  I had no problems deploying this approach to GAE.
Note that the key store can also be created using Java’s keytool.

- David



public static void createKeyStore(String filename, String ksPassword,
byte[] actualKeyToStore, String cryptoAlgorithmName,
                String keyAliasName) throws Exception
        {
                KeyStore ks = KeyStore.getInstance("JCEKS");

                char[] keyStorePassword = ksPassword.toCharArray();
                ks.load(null, keyStorePassword);

                SecretKey secretKey = new SecretKeySpec(actualKeyToStore,
cryptoAlgorithmName);

                // save secret key with alias name for access; use same pwd as
keystore for simplicity
                KeyStore.SecretKeyEntry skEntry = new
KeyStore.SecretKeyEntry(secretKey);
                ks.setEntry(keyAliasName, skEntry, new
KeyStore.PasswordProtection(keyStorePassword));

                // save the keystore
                FileOutputStream fos = new FileOutputStream(filename);
                ks.store(fos, keyStorePassword);
                fos.close();
        }

private static SecretKey readKeyStoreValue(InputStream is, String
ksPassword, String keyAliasName) throws Exception
        {
                KeyStore ks = KeyStore.getInstance("JCEKS");

                char[] keyStorePassword = ksPassword.toCharArray();
                ks.load(is, keyStorePassword);
                is.close();

                Entry retrievedEntry = ks.getEntry(keyAliasName, new
KeyStore.PasswordProtection(keyStorePassword));

                SecretKey retrievedSecretKey = null;
                if (retrievedEntry instanceof KeyStore.SecretKeyEntry)
                {
                        KeyStore.SecretKeyEntry retrievedSecretKeyEntry =
(KeyStore.SecretKeyEntry) retrievedEntry;
                        retrievedSecretKey = 
retrievedSecretKeyEntry.getSecretKey();
                }
                return retrievedSecretKey;
        }


-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to