Different types of keystore in Java -- BKS

  Pi Ke        2016-07-03 03:00:18       33,452        0          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

BKS 是一種由熱門的第三方 Java 加密函式庫提供者 -- BouncyCastle 提供的金鑰庫格式。它類似於 Oracle JDK 提供的 JKS 金鑰庫。

在開始使用 BKS 之前,必須下載並安裝 BouncyCastle 提供者。若要下載提供者,請前往 BouncyCastle 下載頁面。可以透過在 java.security 檔案中新增項目來安裝提供者。

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

N 代表提供者清單中的提供者索引。

建立 BKS 金鑰庫

若要建立 BKS 金鑰庫,只需建立「BKS」的 KeyStore 執行個體,並載入 null 輸入串流和 null 密碼。

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

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

儲存秘密金鑰

與 JKS 不同,秘密金鑰可以儲存在 BKS 金鑰庫中。在儲存金鑰之前,可能需要 不受限制的策略檔案

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());

儲存私密金鑰

除了秘密金鑰之外,也可以將私密金鑰儲存在 BKS 中。這需要同時儲存對應的憑證鏈。否則,將會擲回例外。

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());

儲存憑證

有時當需要信任儲存庫時,不需要在金鑰庫中儲存金鑰,只需要儲存憑證即可。BKS 支援在沒有對應私密金鑰的情況下儲存憑證。

 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());

請注意,若要儲存憑證,通常不需要密碼,因為憑證通常不需要受到保護。

載入金鑰

從金鑰庫載入金鑰時,只需要指定金鑰項目的別名。如果是私密金鑰,您可能想要使用相同的別名來載入憑證鏈。

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());
}

輸出可能如下所示

  [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

載入憑證

這類似於載入金鑰,需要憑證的別名才能載入。

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());

輸出可能如下所示

  [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

刪除項目

在金鑰庫中刪除項目是一項簡單的任務。項目可以是秘密金鑰、私密金鑰和憑證。只需要指定別名。

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());

若要使刪除生效,需要再次儲存金鑰庫,否則,項目不會真正儲存。

除了 BKS 之外,BouncyCastle 還提供了另外兩種金鑰庫實作:BouncyCastlePKCS12

Keystore.BouncyCastle 或 Keystore.UBER 只有在命令列提供密碼時才能與 keytool 搭配使用,因為整個金鑰庫都使用基於 SHA1 和 Twofish 的 PBE 加密。PBEWithSHAAndTwofish-CBC。這使得整個金鑰庫能夠抵抗篡改和檢查,並強制驗證。Sun JDK 提供的 keytool 即使沒有提供密碼也會嘗試載入金鑰庫,但此版本無法做到這一點。

PKCS12 提供與一般金鑰庫略有不同的情況,金鑰庫密碼目前是儲存金鑰時使用的唯一密碼。否則,它支援所有使其能夠與 keytool 搭配使用的必要功能。在某些情況下,其他函式庫始終預期處理 Sun 憑證,如果情況如此,請使用 PKCS12-DEF,並且金鑰庫產生的憑證將使用預設提供者製作。

JAVA  KEYSTORE  BOUNCYCASTLE  BKS 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

Programming alone vs programming watched by others