guozhang

          Java Beginner

          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:

          1.JPG   

          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:

          2.JPG


             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.JPG   

          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):

           

              4.JPG

             In this example, I put a HelloKeytool key into the keystore. Now, the keystore becomes:

          5.JPG

          4. Export a certificate

              Taking advantage of keytool, you can export an X.509 certificate:

          6.JPG

             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.

          7.JPG

              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 2005-10-15

                 *   

                 * 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\\桌面
          \                                                                        \HelloKeytool.cer"; 

                  if(args.length > 0)

                        certFile = args[0];

                 

                  FileInputStream in = new FileInputStream(certFile);

               

                  CertificateFactory cf =  CertificateFactory.getInstance("X.509");

                  X509Certificate x509Cert = (X509Certificate)
                                                                                   cf.generateCertificate(in);

                  printX509Certificate(x509Cert);

                  

                  }

           

               public static void printX509Certificate(X509Certificate
                                                                            x509Cert) throws Exception{

                      System.out.println("版本:   V" + x509Cert.getVersion());

                      System.out.println("序列號:  "  +

                                     byteArray2HexString(x509Cert.getSerialNumber()
                                                                                               .toByteArray()));

                      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("簽名:  " + 
                             byteArray2HexString(x509Cert.getSignature()));

                      System.out.println("認證指紋(MD5): " + 
                            
          byteArray2HexString(doFingerPrint(
                                                                x509Cert.getEncoded(), "MD5"), ":"));

                      System.out.println("認證指紋(SHA): " +
                           
          byteArray2HexString(doFingerPrint(
                                                                x509Cert.getEncoded(), "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 2c 06 07 2a 86 48 ce 38 04 01 30 82 01 1f 02 81 81 00 fd 7f 53 81 1d 75 12 29 52 df 4a 9c 2e ec e4 e7 f6 11 b7 52 3c ef 44 00 c3 1e 3f 80 b6 51 26 69 45 5d 40 22 51 fb 59 3d 8d 58 fa bf c5 f5 ba 30 f6 cb 9b 55 6c d7 81 3b 80 1d 34 6f f2 66 60 b7 6b 99 50 a5 a4 9f 9f e8 04 7b 10 22 c2 4f bb a9 d7 fe b7 c6 1b f8 3b 57 e7 c6 a8 a6 15 0f 04 fb 83 f6 d3 c5 1e c3 02 35 54 13 5a 16 91 32 f6 75 f3 ae 2b 61 d7 2a ef f2 22 03 19 9d d1 48 01 c7 02 15 00 97 60 50 8f 15 23 0b cc b2 92 b9 82 a2 eb 84 0b f0 58 1c f5 02 81 81 00 f7 e1 a0 85 d6 9b 3d de cb bc ab 5c 36 b8 57 b9 79 94 af bb fa 3a ea 82 f9 57 4c 0b 3d 07 82 67 51 59 57 8e ba d4 59 4f e6 71 07 10 81 80 b4 49 16 71 23 e8 4c 28 16 13 b7 cf 09 32 8c c8 a6 e1 3c 16 7a 8b 54 7c 8d 28 e0 a3 ae 1e 2b b3 a6 75 91 6e a3 7f 0b fa 21 35 62 f1 fb 62 7a 01 24 3b cc a4 f1 be a8 51 90 89 a8 83 df e1 5a e5 9f 06 92 8b 66 5e 80 7b 55 25 64 01 4c 3b fe cf 49 2a 03 81 85 00 02 81 81 00 d9 5b 4c e4 f9 3b 52 69 91 2d 3c e2 01 af de 86 c9 55 ab c5 c8 c1 f6 c9 f5 6a 30 f5 ce 6a c7 d6 5a 4e 1e 99 c8 2e 72 34 17 76 bb f5 24 db bd bf b5 0e f2 19 71 08 87 84 eb 38 08 b1 d5 cc 71 8e db 2b cb d2 93 42 28 37 b4 0e 50 77 5e f7 94 6e 86 e4 8d 4c 5b 64 00 d5 fd 39 4e 03 2e e3 cc f7 b7 bd f0 cf 5b d6 3a 09 2f d7 9e da ad 11 b8 ab 87 df f6 43 cb 96 ac 39 a9 ed 37 13 00 f6 b0 16

          簽名:  30 2c 02 14 50 e7 82 89 55 19 b6 fb 4f c7 fb 4f e5 cd 17 d3 2e d6 27 d3 02 14 65 3c af cb 56 45 82 d2 8e b5 79 02 1b 09 15 e5 84 ec ae fe

          認證指紋(MD5): df:89:1f:c9:f1:27:75:3c:2c:f6:14:f3:94:f9:7a:35

          認證指紋(SHA):

           a8:a8:ff:48:a5:51:13:36:8d:25:1e:a2:75:bb:e2:59:a3:8f:27:7b

           

            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:

          8.JPG

           

              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:     fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669

              455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f f26660b7

              6b9950a5 a49f9fe8 047b1022 c24fbba9 d7feb7c6 1bf83b57 e7c6a8a6 150f04fb

              83f6d3c5 1ec30235 54135a16 9132f675 f3ae2b61 d72aeff2 2203199d d14801c7

              q:     9760508f 15230bcc b292b982 a2eb840b f0581cf5

              g:     f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82 f9574c0b 3d078267

              5159578e bad4594f e6710710 8180b449 167123e8 4c281613 b7cf0932 8cc8a6e1

              3c167a8b 547c8d28 e0a3ae1e 2bb3a675 916ea37f 0bfa2135 62f1fb62 7a01243b

              cca4f1be a8519089 a883dfe1 5ae59f06 928b665e 807b5525 64014c3b fecf492a

           

            y:

              d95b4ce4 f93b5269 912d3ce2 01afde86 c955abc5 c8c1f6c9 f56a30f5 ce6ac7d6

              5a4e1e99 c82e7234 1776bbf5 24dbbdbf b50ef219 71088784 eb3808b1 d5cc718e

              db2bcbd2 93422837 b40e5077 5ef7946e 86e48d4c 5b6400d5 fd394e03 2ee3ccf7

              b7bdf0cf 5bd63a09 2fd79eda ad11b8ab 87dff643 cb96ac39 a9ed3713 00f6b016

           

            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 2C 02 14 50 E7 82 89   55 19 B6 FB 4F C7 FB 4F  0,..P...U...O..O

          0010: E5 CD 17 D3 2E D6 27 D3   02 14 65 3C AF CB 56 45  ......'...e<..VE

          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”, “KeytoolHello123”);

              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


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          搜索

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 怀来县| 当雄县| 甘德县| 应用必备| 东辽县| 开远市| 绥化市| 凤山市| 林周县| 宁安市| 昭平县| 金塔县| 乌拉特中旗| 闽清县| 卢氏县| 石门县| 奉节县| 濮阳市| 永川市| 京山县| 昭通市| 梧州市| 黑山县| 西乌珠穆沁旗| 吉水县| 武功县| 沁阳市| 玛曲县| 什邡市| 榆树市| 普宁市| 延安市| 洞头县| 桂林市| 务川| 沿河| 平遥县| 苏州市| 黎川县| 盱眙县| 庐江县|