Search code examples
javasecuritykeystoreprivate-key

KeyStore not saving to file


I am trying to store multiple private keys in a JKS file using the Java KeyStore library. I created a method which writes and reads to the JKS file but the private key isn't being saved in the file.

When I store something into the KeyStore I can get all the aliases in the keystore and the new key is there. Once the method is closed and the same key is attempted to be pulled it does not find the key.

Main.java

public static void main(String[] args) throws Exception {
    //Create keys
    main m = new main();
    m.getOrSetPrivateKey("123", "123", privateKey, false);

    PrivateKey p = m.getOrSetPrivateKey("123", "123", null, true);

    if (p.equals(c.getPriv_key()))
        System.err.println("Equal");
    else
        System.err.println("Not equal !!!!!!!!");

}


private synchronized PrivateKey getOrSetPrivateKey(String alias, String id, PrivateKey c, boolean read ) throws InterruptedException, IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, InvalidKeySpecException, NotSupportedException, UnrecoverableKeyException {
    PrivateKey key = null; 

    InputStream inpusStream = new FileInputStream(getFile2(Constants.JKS_PRIVATE_FILE_NAME));
    KeyStore keyStore = null;
    try {
        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(inpusStream, Constants.JKS_PRIVATE_FILE_PASSWORD);
    } finally {
        if (inpusStream != null)
            inpusStream.close();
    }
    Enumeration<String> s = keyStore.aliases();

    while (s.hasMoreElements())
        System.err.println("[ " + s.nextElement() + " ]");

    //Generate password for this private key
    char [] pass = getKeyPassword(c, alias, id);


    if (read == true) { //If reading/getting private key from file store
        boolean isKeyEntry = keyStore.isKeyEntry(alias);//Check if there is a key with the alias deviceSerialnumber
        if (!isKeyEntry) {//No key with this alias exists
            throw new KeyStoreException("No key with alias " + alias + " exists!");
        }

        key = (PrivateKey) keyStore.getKey(alias, pass);

    } else { //Writing/ saving key to the file store
        keyStore.setKeyEntry(alias, c , pass, new Certificate[] { createCertificate() });
        FileOutputStream out = new FileOutputStream(new File(Constants.JKS_PRIVATE_FILE_NAME), true);
        try { 
            keyStore.store(out, pass);

            System.out.println("Alias exists = " + keyStore.containsAlias(alias));
        } finally { 
            if (out != null)
                out.close();
        } 
    }

    s = keyStore.aliases();

    while (s.hasMoreElements())
        System.err.println("( " + s.nextElement() + " )");

    return key;
}

Output:

[ mykey ]
( 123 )
( mykey )
Alias exists = true
[ mykey ]
Exception in thread "main" java.security.KeyStoreException: No key with alias 123 exists!

Why is the key not being saved to the JKS file file?


Solution

  • The problem was in the FileOutputStream was pointing to the wrong file.

    FileOutputStream out = new FileOutputStream(new File(Constants.JKS_PRIVATE_FILE_NAME), true);
    

    Should be using the getFile2 method like this:

    FileOutputStream out = new FileOutputStream(getFile2(Constants.JKS_PRIVATE_FILE_NAME));
    

    As Palamino pointed out, don't need to include true in the FileOutputStream constructor.

    Also the key store should have been using the JKS file password, not the password that is generated by getKeyPassword().

    Changed this:

    keyStore.store(out, pass);
    

    To use the JKS file password, like this:

    keyStore.store(out, Constants.JKS_PRIVATE_FILE_PASSWORD);