Different types of keystore in Java -- BKS

English 简体中文 繁体中文 ภาษาไทย Tiếng Việt
Summary

BKS is a keystore format from the BouncyCastle cryptographic library, serving as an alternative to Oracle's JKS for Java applications. Developers can use BKS to securely store various cryptographic assets, including secret keys, private keys alongside their certificate chains, and individual X.509 certificates for trust stores. The process involves installing the BouncyCastle provider, then creating, loading, storing, and deleting entries using standard KeyStore API calls with the "BKS" type. Operations like storing private keys require an associated certificate chain, while certificates can be stored independently. BouncyCastle also provides other keystore implementations like BouncyCastle (UBER) and PKCS12, each with specific encryption and password handling characteristics.

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

  COMMENTS

0

No comment for this article.