Search code examples
javaencryptionkeystore

The system cannot find the file specified trying to create .jks file


I'm currently learning encryption/decryption techniques in Java and one major problem I have come across is storing the key in a .jks file and being able to load it in during different launches. In my calling class it calls the constructor and this is the code for it:

public Encrypt_Decrypt() throws NoSuchAlgorithmException, NoSuchPaddingException
{
    Cipher cipher = Cipher.getInstance("AES");
    SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
    byte[] iv = new byte[cipher.getBlockSize()];
    randomSecureRandom.nextBytes(iv);
    IvParameterSpec ivParams = new IvParameterSpec(iv);
    ivSpec = ivParams;

    SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
    byte[] keyBytes = secretKey.getEncoded();
    SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES");
    key = sks;
    KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(key);
    KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection("password".toCharArray());
    try
    {
        File f = new File("keystore.jks");
        KeyStore keyStore = KeyStore.getInstance("JKS");
        java.io.FileInputStream fis = null;
        try
        {
            fis = new java.io.FileInputStream("keystore");
        }
        finally
        {
            if (fis != null)
            {
                fis.close();
            }
        }
        keyStore.load(fis, "password".toCharArray());

        keyStore.setEntry("key", entry, protParam);

        try (FileOutputStream fout = new FileOutputStream(f))
        {
            keyStore.store(fout, "password".toCharArray());
            ;
        }
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
    }
}

After launching this code in the calling class, this is the error it returns: keystore (The system cannot find the file specified)

In my code I create the file so why is it having an issue? I looked in my project folder and it is not being saved there so what do I have to do to be able to create, store and use this file without issues?


Solution

  • The keystore (The system cannot find the file specified) message relates to this line:

    new java.io.FileInputStream("keystore");
    

    It looks like that should have been using the File f? Something similar to how the FileOutputStream is handled just below works well:

    try (FileInputStream fis = new FileInputStream(f)) {
        keyStore.load(fis, "password".toCharArray());
    }
    

    For reference, there's another error waiting there. Trying to store the AES symmetric key in the JKS keystore results in this error:

    java.security.KeyStoreException: Cannot store non-PrivateKeys
        at sun.security.provider.JavaKeyStore.engineSetKeyEntry(JavaKeyStore.java:258)
        at sun.security.provider.JavaKeyStore$JKS.engineSetKeyEntry(JavaKeyStore.java:56)
        at java.security.KeyStoreSpi.engineSetEntry(KeyStoreSpi.java:550)
        at sun.security.provider.KeyStoreDelegator.engineSetEntry(KeyStoreDelegator.java:179)
        at sun.security.provider.JavaKeyStore$DualFormatJKS.engineSetEntry(JavaKeyStore.java:70)
        at java.security.KeyStore.setEntry(KeyStore.java:1557)
        at KeystoreTest.main(KeystoreTest.java:44)
    

    This is because the JKS storetype only supports public/private keys - also here.

    With a new JCEKS keystore instead, your example code then worked fine:

    File f = new File("keystore.jceks");
    KeyStore keyStore = KeyStore.getInstance("JCEKS");