KeyStore
KeyStore
As its name indicates, KeyStore is used for storage of keys (keys’ shelter). In windows platform, KeyStore is represented by a file with a suffix called .keystore. Additionally, there is a utility with the name keytool which assists us with the creation, modification/management of keystores.
For instance
1. Creation
An instance of generating a new keystore file comes next:
You’re supposed to be pay attention to those options of keytool.
keytool | |
Option |
Specification |
-genkey |
Abbreviation of “Generate key”, meaning that we intend to get a key generated |
-alias |
The alias name of this key which can be exploited to refer this key |
-keystore |
The location of this keystore. If this option isn’t provided, the default keystore will be used. The default keystore is located in the ${user.lib} directory and merely has a suffix. In my windows system, it is “C:\Documents and Settings\GuoZhang\.keystore”. |
KeyStores are password-protected, which means that you will be authenticated before you have the authority to access it. In our example, WorldHello is assigned to be the password of HelloWorld keystore. In addition, I set HelloWorld123 as the password of “HelloWorld” key.
Graphically, the demonstrated example has following hierarchy:
Warning: Location is not a attribute of keystore. A keystore can be stored in any directory if you like.
2. List
To see what on earth does a keystore store, we can make use of keytool as well (using the –list option can achieve the goal):
3. Add more entries
Once knowing the password of a keystore, you are able to add more entries into that store (Of course, keytool utility will do it for you):
In this example, I put a HelloKeytool key into the keystore. Now, the keystore becomes:
4. Export a certificate
Taking advantage of keytool, you can export an X.509 certificate:
The key point here is the –export option, which forces keytool to create a certificate via a key (specified by the –alias option) in the keystore (as the –keystore option indicates). The generated certificate is in common used form—X.509.
As you might know, this certificate is a self-signed certificate for it has the same issuer and subject.
5. Retrieve info from X.509 certificate programmatically
JCA (Java Certificate Architecture) provides some useful classes for programmers to retrieve information from an X.509 certificate. Here is an example:
X509CertificateDumper.java |
/* * * Created on * * author: Zhang Guo */ package org.zg.cert; import java.io.FileInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public class X509CertificateDumper { public static void main(String[] args) throws Exception { String certFile = "C:\\Documents and Settings\\ZhangGuo\\桌面 if(args.length > 0) certFile = args[0]; FileInputStream in = new FileInputStream(certFile); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate x509Cert = (X509Certificate) printX509Certificate(x509Cert); } public static void printX509Certificate(X509Certificate System.out.println("版本: V" + x509Cert.getVersion()); System.out.println("序列號: " + byteArray2HexString(x509Cert.getSerialNumber() System.out.println("簽名算法: " + x509Cert.getSigAlgName()); System.out.println("頒發者: " + x509Cert.getIssuerDN()); System.out.println("有效起始時間: " + x509Cert.getNotBefore()); System.out.println("有效終止時間: " + x509Cert.getNotAfter()); System.out.println("主題: " + x509Cert.getSubjectDN()); System.out.println("公鑰: " + byteArray2HexString(x509Cert.getPublicKey().getEncoded())) ; System.out.println("認證指紋(MD5): " + System.out.println("認證指紋(SHA): " + } public static byte[] doFingerPrint(byte[] data, String algorithm) throws NoSuchAlgorithmException{ return MessageDigest.getInstance(algorithm).digest(data); } public static String byteArray2HexString(byte[] data, String delimiter) { StringBuffer buffer = new StringBuffer(); for(int i = 0; i < data.length - 1; i++) buffer.append(byte2HexString(data[i]) + delimiter); buffer.append(byte2HexString(data[data.length - 1])); return buffer.toString(); } public static String byteArray2HexString(byte[] data) { return byteArray2HexString(data, " "); } public static String byte2HexString(byte byt) { String result = Integer.toHexString(byt & 0xff); return (result.length() == 1) ? ("0" + result) : result; } } |
The snippet above is rather intuitive. So is the output:
版本: V1 序列號: 43 50 b8 e5 簽名算法: SHA1withDSA 頒發者: CN=張 果, OU=人工智能實驗室, O=電子科技大學計算機系, L=成都市, ST=四川省, C=CN 有效起始時間: Sat Oct 15 16:08:05 CST 2005 有效終止時間: Fri Jan 13 16:08:05 CST 2006 主題: CN=張 果, OU=人工智能實驗室, O=電子科技大學計算機系, L=成都市, ST=四川省, C=CN 公鑰: 30 82 01 b8 30 82 01 簽名: 30 認證指紋(MD5): df:89: 認證指紋(SHA): a8:a8:ff:48:a5:51:13:36:8d:25:1e:a2:75:bb:e2:59:a3: |
If you compare the output with what you see in the certificate in windows platform, you might wonder why the two public keys don’t go with each other. Actually, what you see in windows is the last 132 bytes of the whole public key’s encoded form. That is, the previous program I developed will get all the encoded form (full contents) of the public key.
In addition, the snippet retrieves the finger print of the certificate, which can be got by keytool utility as well:
As a matter of fact, the toString() method of X509Certificate class is quite nice for dumping itself. The following output is the behavior of X509Certificate’s toString():
toString() of X509Certificate class |
[ [ Version: V1 Subject: CN=張 果, OU=人工智能實驗室, O=電子科技大學計算機系, L=成都市, ST=四川省, C=CN Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3 Key: Sun DSA Public Key Parameters:DSA p: fd 455d4022 51fb593d 8d58fabf c 6b q: g: f7e 5159578e bad cca y: d95b4ce db2bcbd2 93422837 b40e5077 5ef7946e 86e48d b7bdf0cf 5bd Validity: [From: Sat Oct 15 16:08:05 CST 2005, To: Fri Jan 13 16:08:05 CST 2006] Issuer: CN=張 果, OU=人工智能實驗室, O=電子科技大學計算機系, L=成都市, ST=四川省, C=CN SerialNumber: [ 4350b8e5] ] Algorithm: [SHA1withDSA] Signature: 0000: 30 0010: E5 CD 17 D3 2E D6 27 D3 02 14 65 0020: 82 D2 8E B5 79 02 1B 09 15 E5 84 EC AE FE ....y......... ] |
6. Dump KeyStore
As mentioned previously, KeyStore is a set of keys. To dump it, the key point is to obtain an instance of KeyStore, which can be achieved by invoking KeyStore’s getInstance() method. Given the type of the KeyStore, getInstance() will return an instance of KeyStore:
KeyStore ks = KeyStore.getInstance(“JKS”);
For password-protected KeyStores on windows, “JKS” might be their types. In fact, “JKS” is the default keystore type and can be found by calling KeyStore class’ static method--getDefaultType(). The default keystore type is defined in <JRE_HOME>\lib\security\java.security:
<JRE_HOME>\lib\security\java.security |
# # Default keystore type. # keystore.type=jks |
By the way, type is case-insensitive. That is, “JKS”, “jKs”, “JkS” and so on will be treated as counterparts.
Once gaining a instance of KeyStore, you’re capable of extracting as much information as you like. You, however, are supposed to load the ks from a certain certificate file. A keystore cannot be used before it’s loaded:
ks.load(new FileInputStream(“MyKeyStore.keystore”), “WorldHello”.toCharArray());
The above fragment loads the ks from MyKeyStore.keystore with its corresponding password—WorldHello.
Next can we do some extraction. For instance, I’d like to get some information about “HelloKeytool” key:
Key key = ks.getKey(“HelloKeytool”, “KeytoolHello
The key object is a private key. You can get it through its alias name and password. If you intend to get the Certificate info about “HelloKeytool”, you may write:
Certificate cert = ks.getCertificate(“HelloKeytool”);
It’s not necessary to generate a certificate file before you use the Certificate object. What’s more, extracting info from a certificate need no password since it’s “public”. Certificates are made to be distributed, sent to others and make others have a idea of them.
posted on 2005-12-21 16:24 Guo Zhang 閱讀(1830) 評論(0) 編輯 收藏 所屬分類: Java