Different types of keystore in Java -- BKS

  Pi Ke        2016-07-03 03:00:18       33,245        0    

BKS is a keystore format provided by the popular third party Java cryptographic library provider -- BouncyCastle. It is a keystore similar to the JKS provided by Oracle JDK. 

Before starting to use BKS, the BouncyCastle provider has to be downloaded and installed. To download the provider, please go to BouncyCastle download page. The provider can be installed by adding an entry in the java.security file.

security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

N means the provider index in the provider list.

Creating BKS keystore

To create a BKS keystore, you just need to create a KeyStore instance of "BKS" and load a null input stream and null password.

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(null, null);

keyStore.store(new FileOutputStream("mytestkeys.bks"), "password".toCharArray());

Storing secret key

Different from JKS, secret keys can be stored in BKS keystore. Before storing keys, the unrestricted policy files may be needed.

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
Key key = keyGenerator.generateKey();

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

keyStore.setKeyEntry("aeskey", key, "password".toCharArray(), null);

keyStore.store(new FileOutputStream("mytestkeys.bks"), "password".toCharArray());

Storing private key

Instead of secret keys, private keys can also be stored in BKS. It requires the corresponding certificate chain to be stored at the same time. Otherwise, exception would be thrown.

CertAndKeyGen gen = new CertAndKeyGen("RSA","SHA1WithRSA");
gen.generate(1024);
 
Key key=gen.getPrivateKey();
X509Certificate cert=gen.getSelfCertificate(new X500Name("CN=ROOT"), (long)365*24*3600);
 
X509Certificate[] chain = new X509Certificate[1];
chain[0]=cert;

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

keyStore.setKeyEntry("rsakey", key, "password".toCharArray(), chain);

keyStore.store(new FileOutputStream("mytestkeys.bks"), "password".toCharArray());

Storing certificate

Sometimes when a trust store is needed, no keys need to be stored in the keystore, only the certificates are needed. BKS supports storing certificate without corresponding private key.

 CertAndKeyGen gen = new CertAndKeyGen("RSA","SHA1WithRSA");
 gen.generate(1024);
     
 X509Certificate cert=gen.getSelfCertificate(new X500Name("CN=SINGLE_CERTIFICATE"), (long)365*24*3600);
 
 KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
 keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

 keyStore.setCertificateEntry("rsacert", cert);

 keyStore.store(new FileOutputStream("mytestkeys.bks"), "password".toCharArray());

Note, to store a certificate, there is no password needed since a certificate no need to be protected normally.

Loading key

When loading a key from the keystore, only need to specify the alias of the key entry. If it's a private key, you may want to use the same alias to load the certificate chain.

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

Key key = keyStore.getKey("rsakey", "password".toCharArray());

Certificate[] chain = (Certificate[]) keyStore.getCertificateChain("rsakey");
for(java.security.cert.Certificate cert:chain){
    System.out.println(cert.toString());
}

The output may look like

  [0]         Version: 3
         SerialNumber: 1676692330
             IssuerDN: CN=ROOT
           Start Date: Sun Jul 03 15:29:46 CST 2016
           Final Date: Mon Jul 03 15:29:46 CST 2017
            SubjectDN: CN=ROOT
           Public Key: RSA Public Key
            modulus: 813dd8db5d26940347116b4986eb7bc89fa423c9d9374a422f2951c9a258458175d97ac586a94da851885453e368e249e1c3b14751a80e8d3ec4dc6be19bfd968fa59209f7d032215946e4ad9b0e261d488a35af250e8dbcb9d0fa5c0c309a2be8fe9535950b9b4c6cdca25f9c2e50ed2786bcbce6b2971c80edef9691ae5d63
    public exponent: 10001

  Signature Algorithm: SHA1WITHRSA
            Signature: 00362e9e84c5dd02ed6cf589625257abe55d3c5c
                       fdde5cee362222147b5870b89909e3008567e29b
                       9b4b5c72342219d167dd058b7d1c59ca4696db4e
                       28ee791989e731fba86ebb1b2caedce98af2a5e7
                       44a026cc01d9b4b65e0a65b19a684b1b99b71afe
                       4d27412e852d977a2855e9f011918ac528555469
                       aeb8406756185b44

Loading certificate

This is similar to loading key, the alias is needed for the certificate to be loaded.

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

Certificate cert = (Certificate) keyStore.getCertificate("rsakey");
System.out.println(cert.toString());

The output may look like

  [0]         Version: 3
         SerialNumber: 1676692330
             IssuerDN: CN=ROOT
           Start Date: Sun Jul 03 15:29:46 CST 2016
           Final Date: Mon Jul 03 15:29:46 CST 2017
            SubjectDN: CN=ROOT
           Public Key: RSA Public Key
            modulus: 813dd8db5d26940347116b4986eb7bc89fa423c9d9374a422f2951c9a258458175d97ac586a94da851885453e368e249e1c3b14751a80e8d3ec4dc6be19bfd968fa59209f7d032215946e4ad9b0e261d488a35af250e8dbcb9d0fa5c0c309a2be8fe9535950b9b4c6cdca25f9c2e50ed2786bcbce6b2971c80edef9691ae5d63
    public exponent: 10001

  Signature Algorithm: SHA1WITHRSA
            Signature: 00362e9e84c5dd02ed6cf589625257abe55d3c5c
                       fdde5cee362222147b5870b89909e3008567e29b
                       9b4b5c72342219d167dd058b7d1c59ca4696db4e
                       28ee791989e731fba86ebb1b2caedce98af2a5e7
                       44a026cc01d9b4b65e0a65b19a684b1b99b71afe
                       4d27412e852d977a2855e9f011918ac528555469
                       aeb8406756185b44

Deleting entry

It's an easy task to delete an entry in a keystore. The entry can be a secret key, private key and certificate. The alias is the only one needs to be specified.

KeyStore keyStore = KeyStore.getInstance("BKS", "BC");
keyStore.load(new FileInputStream("mytestkeys.bks"), "password".toCharArray());

keyStore.deleteEntry("aeskey");

keyStore.store(new FileOutputStream("mytestkeys.bks"), "password".toCharArray());

To make the deletion effective, the keystore needs to be stored again, otherwise, the entries are not really stored.

In addition to BKS, BouncyCastle provides another two implementations of keystore : BouncyCastle and PKCS12.

Keystore.BouncyCastle, or Keystore.UBER will only work with the keytool if the password is provided on the command line, as the entire keystore is encrypted with a PBE based on SHA1 and Twofish.PBEWithSHAAndTwofish-CBC. This makes the entire keystore resistant to tampering and inspection, and forces verification. The Sun JDK provided keytool will attempt to load a keystore even if no password is given, this is impossible for this version. 

PKCS12 provides a slightly different situation from the regular key store, the keystore password is currently the only password used for storing keys. Otherwise it supports all the functionality required for it to be used with the keytool. In some situations other libraries always expect to be dealing with Sun certificates, if this is the case use PKCS12-DEF, and the certificates produced by the key store will be made using the default provider. 

JAVA  KEYSTORE  BOUNCYCASTLE  BKS 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Adapter design pattern explained