How to store a simple key string inside Java KeyStore?

感情迁移 提交于 2019-11-29 18:45:36

问题


I have a file on my FS (a S3 AWS key) that contains a string that is a key I use for encryption process.

I would like to move it a Java KeyStore.

I know how to import a certificate into a KeyStore with keytool but I can't find the way to import a simple string key.

Can you help?


回答1:


I don't see a way to do it with keytool, but some poking about, I wonder if you could store and retrieve it in code as a PasswordBasedEncryption (PBE) SecretKey. (Disclaimer: I haven't tried this myself).

The resources that drove this thought: PBEKeySpec javadoc and CryptoSpec - Using Password Based Encryption example




回答2:


You can do this with PBE and JCEKS. I don't think you can do it with JKS. Solution:

Create a keystore to store and get entries from:

keytool -keystore clientkeystore -genkey -alias client -storetype jceks

Now some code to test it out.

   public static String getPasswordFromKeystore(String entry, String keystoreLocation, String keyStorePassword) throws Exception{

        KeyStore ks = KeyStore.getInstance("JCEKS");
        ks.load(null, keyStorePassword.toCharArray());
        KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());

        FileInputStream fIn = new FileInputStream(keystoreLocation);

        ks.load(fIn, keyStorePassword.toCharArray());

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");

        KeyStore.SecretKeyEntry ske =
                (KeyStore.SecretKeyEntry)ks.getEntry(entry, keyStorePP);

        PBEKeySpec keySpec = (PBEKeySpec)factory.getKeySpec(
                ske.getSecretKey(),
                PBEKeySpec.class);

        char[] password = keySpec.getPassword();

        return new String(password);

    }

    public static void makeNewKeystoreEntry(String entry, String entryPassword, String keyStoreLocation, String keyStorePassword)
            throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
        SecretKey generatedSecret =
                factory.generateSecret(new PBEKeySpec(
                        entryPassword.toCharArray()));

        KeyStore ks = KeyStore.getInstance("JCEKS");
        ks.load(null, keyStorePassword.toCharArray());
        KeyStore.PasswordProtection keyStorePP = new KeyStore.PasswordProtection(keyStorePassword.toCharArray());

        ks.setEntry(entry, new KeyStore.SecretKeyEntry(
                generatedSecret), keyStorePP);

        FileOutputStream fos = new java.io.FileOutputStream(keyStoreLocation);
        ks.store(fos, keyStorePassword.toCharArray());
    }



回答3:


I know this is old; but I came across this same use case.

https://docs.oracle.com/javase/9/tools/keytool.htm#JSWOR-GUID-5990A2E4-78E3-47B7-AE75-6D1826259549

keystores have an importpass options that stores a KeyStore.SecretKeyEntry identified by alias.

So there's that and you could store your string in an alias.




回答4:


I had to do this this afternoon, the solution of @JasonG works but not the keytool options.

Since Java 8 you can use the -importpass option with Keytool, which will help you achieve what you need.

Let's suppose I want to save the sensitive password foobar in the mypass alias in the keystore named myks.jceks protected with the password password here, do the following:

$ keytool -importpass -storetype pkcs12 -alias mypass -keystore myks.p12
Enter keystore password: <password>
Re-enter new password: <password>
Enter the password to be stored: <foobar>
Re-enter password: <foobar>
Enter key password for <mypass>
    (RETURN if same as keystore password): <password>
Re-enter new password: <password>

And then you're good to go to use the same code as @JasonG, I have this in my code:

private Try<String> loadKey(Resource path, String pw) {
    return Try.of(() -> {
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(path.getInputStream(), pw.toCharArray());

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
        SecretKeyEntry ske = (SecretKeyEntry) ks.getEntry("mypass",
                new PasswordProtection(pw.toCharArray()));

        PBEKeySpec keySpec = (PBEKeySpec) factory.getKeySpec(
                ske.getSecretKey(), PBEKeySpec.class);

        return new String(keySpec.getPassword());
    });
}

Note that I have used PKCS12 since JCEKS uses a proprietary format, and it is recommended to migrate to PKCS12 which is an industry standard format.

Besides we had some problems with some Windows machine (running Java 8) being stuck while trying to load the JCEKS store, throwing exceptions. PKCS12 seems a better choice.




回答5:


You can not import in the key store arbitrary strings. In the key store you import certification keys that java libraries are using for authentication of remote hosts.



来源:https://stackoverflow.com/questions/6243446/how-to-store-a-simple-key-string-inside-java-keystore

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!