Different types of keystore in Java -- BKS

  Pi Ke        2016-07-03 03:00:18       33,454        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

When boss walks by