Different types of keystore in Java -- JKS

JKS is Java Keystore, a proprietary keystore type designed for Java. It can be used to store private keys and certificates used for SSL communication, it cannot store secret keys however. The keytool shipped with JDKs cannot extract private keys stored on JKS. This type of keystore usually has an extension of jks.

Next we will show how to operate the JKS keystore with pure Java code.

Create JKS keystore

The simplest method to create a JKS keystore to create an empty keystore. We can first get an instance of KeyStore and then load a null keystore. After loading the null keystore, we just need to call KeyStore.store() with the keystore name and password of the keystore.

Below is a simple demo:

1
2
3
4
5
6
7
8
try {
     KeyStore keyStore = KeyStore.getInstance( "JKS" );
     keyStore.load( null , null );
     
     keyStore.store( new FileOutputStream( "mytestkey.jks" ), "password" .toCharArray());
} catch (Exception ex){
     ex.printStackTrace();
}

Post execution of above call, you will see a keystore named mytestkey.jks in current working directory. Now the keystore is empty without any entries.

Store private key

Now let's store one private key and its associated certificate chain into the keystore. Note we can not store a private key without an associated certificate chain into a keystore using JDK. With some other library or native libraries, you may be able to store a private key without associated certificate chain.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try {
     KeyStore keyStore = KeyStore.getInstance( "JKS" );
     keyStore.load( new FileInputStream( "mytestkey.jks" ), "password" .toCharArray());
     
     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.setKeyEntry( "mykey" , key, "password" .toCharArray(), chain);
     
     keyStore.store( new FileOutputStream( "mytestkey.jks" ), "password" .toCharArray());
} catch (Exception ex){
     ex.printStackTrace();
}

First, we will create a private key and a self signed certificate and then call KeyStore.setKeyEntry() with the specified alias, key, the password for the key and its associated certificate chain. Remember we need to call KeyStore.store() to store the key into the keystore.

The alias is the label of the entry so that it can be found easily later.

Store certificate

We can store certificate on JKS keystore. The certificate to be store should be a X509Certificate. It can be stored on the keystore without associated private key. This process is similar to storing private key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
     KeyStore keyStore = KeyStore.getInstance( "JKS" );
     keyStore.load( new FileInputStream( "mytestkey.jks" ), "password" .toCharArray());
     
     CertAndKeyGen gen = new CertAndKeyGen( "RSA" , "SHA1WithRSA" );
     gen.generate( 1024 );
     
     X509Certificate cert=gen.getSelfCertificate( new X500Name( "CN=SINGLE_CERTIFICATE" ), ( long ) 365 * 24 * 3600 );
     
     keyStore.setCertificateEntry( "single_cert" , cert);
     
     keyStore.store( new FileOutputStream( "mytestkey.jks" ), "password" .toCharArray());
} catch (Exception ex){
     ex.printStackTrace();
}

Loading private key

After storing the keys, we can also load the entries inside the keystore. Here we are saying to load private key, actually it's not the case here, as we described earlier, the private key cannot be extracted from JKS using Java. Here we actually extract the certificate chain of the private key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try {
     KeyStore keyStore = KeyStore.getInstance( "JKS" );
     keyStore.load( new FileInputStream( "mytestkey.jks" ), "password" .toCharArray());
     
     Key key = keyStore.getKey( "alias" , "password" .toCharArray());
//          System.out.println("Private key : "+key.toString());   //You will get a NullPointerException if you uncomment this line
     
     java.security.cert.Certificate[] chain =  keyStore.getCertificateChain( "mykey" );
     for (java.security.cert.Certificate cert:chain){
         System.out.println(cert.toString());
     }
} catch (Exception ex){
     ex.printStackTrace();
}

Note the commented line, the key will be null as expected. We can get the certificate chain as normal though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
[
   Version: V3
   Subject: CN=ROOT
   Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
   Key:  Sun RSA public key, 1024 bits
   modulus: 90980299845597512779139009881469177009407272139633139241921529845092210461181243924599150259446249079941561941533303439718936138867375776965995893255358889228584415558006141961051402385279285497775776996780406808976543439543789816486513982581378223575354716191394304768315366544413052547926792470794374067383
   public exponent: 65537
   Validity: [From: Sat Sep 06 09:57:28 CST 2014,
                To: Sun Sep 06 09:57:28 CST 2015]
   Issuer: CN=ROOT
   SerialNumber: [    206b697b]
 
]
   Algorithm: [SHA1withRSA]
   Signature:
0000: 53 6A FD FE E6 3A 5E 6E   A6 43 C4 F4 D1 56 D4 08  Sj...:^n.C...V..
0010: 7E 3B 8B 73 68 71 56 AB   96 FE 24 E7 2D DC 04 BB  .;.shqV...$.-...
0020: 14 B0 C6 71 8D F0 3E EC   FE D8 5B BB 8C 0F 55 63  ...q..>...[...Uc
0030: 2B 38 8E 45 F1 2D F0 BB   8C 6D 13 A8 11 37 E1 FA  +8.E.-...m...7..
0040: 77 AF C7 73 72 2B 40 4F   74 32 F6 3C 24 E6 AB ED  w..sr+@Ot2.<$...
0050: 2C 6F 19 2E DC 58 5F CB   75 62 40 2F 3E BE 59 99  ,o...X_.ub@/>.Y.
0060: C0 1F 7A 70 15 AF C3 66   B3 4F C9 11 C3 45 59 EF  ..zp...f.O...EY.
0070: 36 F4 1C C9 9B FA 5E 43   A0 28 DB 07 0D F2 53 6E  6.....^C.(....Sn
 
]

Loading certificate

This is similar to loading private key, we need to pass the alias of the certificate we want to extract.

1
2
3
4
5
6
7
8
9
10
try {
     KeyStore keyStore = KeyStore.getInstance( "JKS" );
     keyStore.load( new FileInputStream( "mytestkey.jks" ), "password" .toCharArray());
     
     java.security.cert.Certificate cert = keyStore.getCertificate( "single_cert" );
     
     System.out.println(cert.toString());
} catch (Exception ex){
     ex.printStackTrace();
}

The output will be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
[
   Version: V3
   Subject: CN=SINGLE_CERTIFICATE
   Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
 
   Key:  Sun RSA public key, 1024 bits
   modulus: 99756834215197288877309915243024788596281418171661241282881476656110879586349799740269767889529808199104172091786860877280382867461569439907754755558759387462421169749111354565793974372777424046360810758009149155148290676527032833774084635148674232352006810533640038723102562578516643345287042787777951043863
   public exponent: 65537
   Validity: [From: Sat Sep 06 10:14:33 CST 2014,
                To: Sun Sep 06 10:14:33 CST 2015]
   Issuer: CN=SINGLE_CERTIFICATE
   SerialNumber: [    6943e549]
 
]
   Algorithm: [SHA1withRSA]
   Signature:
0000: 35 58 70 96 F4 35 82 2A   95 9F BB 31 02 6E 7C 29  5Xp..5.*...1.n.)
0010: 4A FE AF EB 2D B5 3A A7   C7 9D 4C 9A 34 2C 5C 46  J...-.:...L.4,\F
0020: C2 82 A8 AC 1A C0 98 A5   67 21 74 7B 1E E2 E5 AC  ........g!t.....
0030: DE B2 1D 87 BE 16 45 9B   D0 2A D3 2B F6 E1 4B 35  ......E..*.+..K5
0040: 27 8B A7 0A EF F2 07 41   90 A6 69 07 BE 87 C5 B1  '......A..i.....
0050: 54 DE DB A2 5A 41 47 3B   3F A7 74 6F 5C C8 8D B4  T...ZAG;?.to\...
0060: C8 65 2B 0F 8E 94 A8 80   C7 8B B5 78 FA C2 9C ED  .e+........x....
0070: 8E EC 28 E4 8E 62 A1 59   6A BC 37 7B 0D FC C7 AF  ..(..b.Yj.7.....
 
]

Import keys and certificates

This process is actually very simple, we first need to load the keystore where the certificate to be imported. Then we also need to load another keystore where we need to import certificate to. Next, we need to get the certificate from source keystore and put it into the destination keystore.

Since we cannot extract private key from JKS, so we can only import certificate to JKS. However, we can extract private keys from other types of keystore(PKCS12) and then store them in JKS keystore.

We will cover other type of keystore in future posts.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值