Java密鑰庫的不同類型 -- JKS


原文:https://www.pixelstech.net/article/1409966488-Different-types-of-keystore-in-Java----JKS

轉載:https://www.cnblogs.com/yangchongxing/p/13834467.html

機器翻譯

Different types of keystore in Java -- JKS

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.

JKS是Java密鑰庫,一種專為Java設計的密鑰庫類型。它可以用來存儲用於SSL通信的私鑰和證書,但是它不能存儲密鑰。JDKs附帶的keytool無法提取JKS上存儲的私鑰。這種類型的密鑰庫通常有jks的擴展。

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

接下來,我們將展示如何使用純Java代碼操作JKS密鑰庫。

Create JKS keystore

創建JKS密鑰庫

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:

創建JKS密鑰庫的最簡單方法是創建空密鑰庫。我們可以首先獲得KeyStore的一個實例,然后加載一個空KeyStore。加載空密鑰庫后,我們只需要調用KeyStore.store()方法並傳遞密鑰庫名稱和密鑰庫的密碼。

下面是一個簡單的演示:

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.

在執行上述調用后,您將看到一個名為mytestkey.jks在當前工作目錄中。現在密鑰庫是空的,沒有任何條目

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.

現在讓我們將一個私鑰及其關聯的證書鏈存儲到密鑰庫中。注意:我們不能使用JDK將沒有相關證書鏈的私鑰存儲到密鑰庫中。對於其他一些庫或本機庫,您可能能夠存儲私鑰,而無需關聯的證書鏈。

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.

首先,我們將創建一個私鑰和一個自簽名證書,然后調用KeyStore.setKeyEntry()方法(參數:別名、私鑰、密碼),私鑰的密碼和證書關聯。記住我們需要調用KeyStore.store()方法把私鑰保存如密鑰庫。

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.

我們可以在JKS密鑰庫中存儲證書。要存儲的證書應為X509證書。它可以存儲在沒有相關私鑰的密鑰庫中。這個過程類似於存儲私鑰。

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.

在存儲密鑰之后,我們還可以加載密鑰庫中的條目。這里我們說的是加載私鑰,實際上這里不是這樣,正如我們前面所描述的,私鑰不能用Java從JKS中提取出來。這里我們實際上提取了私鑰的證書鏈。

try{
    KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(new FileInputStream("mytestkey.jks"),"password".toCharArray());
     
    Key key = keyStore.getKey("mykey", "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.

注意注釋行,鍵將如預期的那樣為null。我們可以正常獲取證書鏈。

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

這與加載私鑰類似,我們需要傳遞要提取的證書的別名。

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:

輸出將是:

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

由於無法從JKS中提取私鑰,所以只能將證書導入JKS。但是,我們可以從其他類型的密鑰庫(PKCS12)中提取私鑰,然后將它們存儲在JKS密鑰庫中。

One final piece of information. Oracle provides two versions of JKS keystore : case sensitive and case insensitive. When calling KeyStore.getInstance("JKS"), a case insensitive version of JKS instance is created, when KeyStore.getInstance("CaseExactJKS") is called, a case sensitive version of JKS instance will be created. Usually case insensitive is recommended as an user should distinguish different entries with different alias names instead of different alias name cases. For more information about case sensitivity, please refer to this post.

最后一條信息。Oracle提供了兩個版本的JKS密鑰庫:區分大小寫和不區分大小寫。當調用KeyStore.getInstance("JKS")時將創建一個不區分大小寫版本的JKS實例。當調用KeyStore.getInstance("CaseExactJKS")時將創建區分大小寫版本的JKS實例。通常建議不區分大小寫,因為用戶應該區分具有不同別名的不同條目,而不是不同的別名大小寫。有關區分大小寫的更多信息,請參閱這篇文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM