Evan
Evan

Reputation: 714

Which KeyStore implementations can be used for storing symmetric keys?

java.security.KeyStore uses KeyStoreSpi implementations to provide keystores of different types. Basic OpenJDK comes with support of JKS, JCEKS and PKCS12 keystore types. The first two implement proprietary Sun/Oracle format and PKCS12 is a public standard.

I know that JCEKS does support symmetric keys and PKCS12 does not. Which other KeyStoreSpi implementations (like Bouncy Castle) provide support of symmetric keys? It looks like devs like to hide such info. E.g. Bouncy Castle docs only mentions:

The fourth is the BCFKS key store which is a FIPS compliant key store which is also designed for general key storage and based on ASN.1. This key store type is encrypted and supports the use of SCRYPT and the storage of some symmetric key types.

Upvotes: 0

Views: 1651

Answers (1)

Michael Fehr
Michael Fehr

Reputation: 6394

Why do you think that a PKCS#12 keystore does not save secret keys in general? I'm working on Desktop OpenJDK 11.x and I do not have any problem in saving and reloading of a secret key with a PKCS#12 keystore.

But you are right - there are some Java implementations where this won't work - just give it a try!

output:

Keystore Type PKCS12
source: https://www.pixelstech.net/article/1420427307-Different-types-of-keystore-in-Java----PKCS12
create a keystore
load the keystore and store a secret key
key after generation length: 32 data: eb6b8efafcee46880ea75b83754442efe4ee9d66ce755698cc803fd7775e4e78
load secret key from keystore
key after loading    length: 32 data: eb6b8efafcee46880ea75b83754442efe4ee9d66ce755698cc803fd7775e4e78

Security warning: the code does not have any exception handling and is for educational purpose only.

code:

import javax.crypto.KeyGenerator;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.security.KeyStore;

public class KeystoreTypePKCS12 {
    public static void main(String[] args) {
        System.out.println("Keystore Type PKCS12");
        // https://stackoverflow.com/questions/64677544/which-keystore-implementations-can-be-used-for-storing-symmetric-keys
        System.out.println("source: https://www.pixelstech.net/article/1420427307-Different-types-of-keystore-in-Java----PKCS12");    
        System.out.println("create a keystore");
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(null, null);
            try (FileOutputStream outStream = new FileOutputStream("keystore.p12") {
                keyStore.store(outStream, "password".toCharArray());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        System.out.println("load the keystore and store a secret key");
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try (FileInputStream inStream = new FileInputStream("keystore.p12")) {
                keyStore.load(inStream, "password".toCharArray());
            }
            // generate an aes secret key
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(256);
            Key key = keyGen.generateKey();
            System.out.println("key after generation length: " + key.getEncoded().length
                    + " data: " + bytesToHex(key.getEncoded()));
            // store it in the keystore
            keyStore.setKeyEntry("secret", key, "password".toCharArray(), null);
            // save the keystore
            try (FileOutputStream outStream = new FileOutputStream("keystore.p12")) {
                keyStore.store(outStream, "password".toCharArray());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        System.out.println("load secret key from keystore");
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try (FileInputStream inStream = new FileInputStream("keystore.p12")) {
                keyStore.load(inputStream, "password".toCharArray());
            }
            Key keyLoad = keyStore.getKey("secret", "password".toCharArray());
            System.out.println("key after loading    length: " + keyLoad.getEncoded().length
                    + " data: " + bytesToHex(keyLoad.getEncoded()));
        } catch (Exception ex){
            ex.printStackTrace();
        }
    }
    
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        return result.toString();
    }
}

Upvotes: 1

Related Questions