Java密钥库类型JKS and JCEKS and PKCS12

Java密钥库类型JKS and JCEKS and PKCS12

Java密钥库类型JKS and JCEKS

Sun's cryptographic libraries provide support for two different proprietary keystores. The traditional keystore, available from the "SUN" provider in the standard JDK, is called the "JKS" keystore.The alternate(代替的) keystore, available from the "SunJCE" provider in the JCE (Java Cryptography Extension), is called the "JCEKS" keystore. Which one should you use? If you're not using the JCE, then the answer is easy. Your only option is to use the JKS keystore. If, however, you have installed the JCE and you are using JCE functionality, then your best bet is the JCEKS keystore. This keystore provides much stronger protection for stored private keys by using Triple DES encryption.


Java的KeyStore提供的三种密钥实体

 A {KeyStore} manages different types of entries.

Each type of entry implements the {KeyStore.Entry} interface.

Three basic {@code KeyStore.Entry} implementations are provided:

KeyStore.PrivateKeyEntry

KeyStore.PrivateKeyEntry

This type of entry holds a cryptographic {@PrivateKey},

which is optionally stored in a protected format to prevent

unauthorized access.  It is also accompanied by a certificate chain

for the corresponding public key.


Private keys and certificate chains are used by a given entity for

self-authentication. Applications for this authentication include software

distribution organizations which sign JAR files as part of releasing

and/or licensing software.

KeyStore.SecretKeyEntry

KeyStore.SecretKeyEntry

This type of entry holds a cryptographic {SecretKey},

which is optionally stored in a protected format to prevent

unauthorized access.

KeyStore.TrustedCertificateEntry

KeyStore.TrustedCertificateEntry

This type of entry contains a single public key {@Certificate}

belonging to another party. It is called a <i>trusted certificate</i>

because the keystore owner trusts that the public key in the certificate

indeed belongs to the identity identified by the <i>subject</i> (owner)

of the certificate.


密钥库格式的转换(PKCS12-->JKS)

JKS文件(通常为*.jks或*.keystore,扩展名无关)可以通过Java原生工具——KeyTool生成;

而PKCS#12文件(通常为*.p12或*.pfx,意味个人信息交换文件),则是通过更为常用的OpenSSL工具产生。 

当然,这两者之间是可以通过导入/导出的方式进行转换的!当然,这种转换需要通过KeyTool工具进行! 

现在有一个pkcs12格式的密钥库,要将他转换为jks类型的密钥库,则可以使用keytool的importkeystore命令进行转换

E:\openssl\server>keytool -importkeystore -help
keytool -importkeystore [选项]...

从其他密钥库导入一个或所有条目

选项:

 -srckeystore <srckeystore>            源密钥库名称
 -destkeystore <destkeystore>          目标密钥库名称
 -srcstoretype <srcstoretype>          源密钥库类型
 -deststoretype <deststoretype>        目标密钥库类型
 -srcstorepass <arg>                   源密钥库口令
 -deststorepass <arg>                  目标密钥库口令
 -srcprotected                         受保护的源密钥库口令
 -srcprovidername <srcprovidername>    源密钥库提供方名称
 -destprovidername <destprovidername>  目标密钥库提供方名称
 -srcalias <srcalias>                  源别名
 -destalias <destalias>                目标别名
 -srckeypass <arg>                     源密钥口令
 -destkeypass <arg>                    目标密钥口令
 -noprompt                             不提示
 -providerclass <providerclass>        提供方类名
 -providerarg <arg>                    提供方参数
 -providerpath <pathlist>              提供方类路径
 -v                                    详细输出

使用 "keytool -help" 获取所有可用命令

E:\openssl\server>
E:\openssl\server>keytool -importkeystore -v -srckeystore server.p12 -srcstoretype pkcs12 -srcstorep
ass 123456 -destkeystore server.keystore -deststoretype jks -deststorepass 123456
已成功导入别名 1 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
[正在存储server.keystore]

这样就算是转换完成了。

然后查看新生成的密钥库详细信息

E:\openssl\server>keytool -list -keystore server.keystore -storepass 123456 -v

密钥库类型: JKS
密钥库提供方: SUN

您的密钥库包含 1 个条目

别名: 1
创建日期: 2014-7-5
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: [email protected], CN=www.ceit.com, OU=rjgc, O=rjxy, L=sy, ST=sy, C=CN
发布者: [email protected], CN=wwww.cnivi.cn, OU=rjxy, O=www.cnivi.cn, L=sy, ST=sy, C=CN
序列号: d2834a3c2b6e5c7c
有效期开始日期: Tue May 20 02:32:55 CST 2014, 截止日期: Fri May 17 02:32:55 CST 2024
证书指纹:
         MD5: C2:39:D0:58:1F:4C:26:E5:A1:07:48:F9:E4:D3:A8:37
         SHA1: 2C:29:EB:D2:BD:D0:9E:16:84:23:0E:6B:08:FB:70:58:8D:8E:92:C0
         SHA256: 33:7A:C6:36:1F:56:3A:02:6C:0B:2B:61:EB:11:2D:DE:0B:E1:A1:EA:C5:62:69:DD:73:C1:D5:8E
:95:E2:AF:C3
         签名算法名称: SHA1withRSA
         版本: 1


*******************************************
*******************************************


Java读取PKCS12格式的密钥库

@Test
public void test098() throws Exception {
    String pass = "123456";
    String name = "E:\\openssl\\server\\server.p12";
    FileInputStream in = new FileInputStream(name);
    KeyStore ks = KeyStore.getInstance("PKCS12");
    ks.load(in, pass.toCharArray());
    Enumeration e = ks.aliases();
    while (e.hasMoreElements()) {
        System.out.println(e.nextElement());
    }
}


使用JCEKS密钥库存储DESede对称密钥

-genseckey   命令详细的信息

E:\keytool>keytool -genseckey -help
keytool -genseckey [选项]...

生成对称密钥

选项:

 -alias <alias>                  要处理的条目的别名
 -keypass <arg>                  密钥口令
 -keyalg <keyalg>                密钥算法名称
 -keysize <keysize>              密钥位大小
 -keystore <keystore>            密钥库名称
 -storepass <arg>                密钥库口令
 -storetype <storetype>          密钥库类型
 -providername <providername>    提供方名称
 -providerclass <providerclass>  提供方类名
 -providerarg <arg>              提供方参数
 -providerpath <pathlist>        提供方类路径
 -v                              详细输出
 -protected                      通过受保护的机制的口令

命令行:生成对称密钥

E:\keytool>keytool -genseckey -alias cnivi.seckey -keypass 034039 -keyalg DESede -keysize 168 -keystore cnivi.keystore -storepass 123456 -storetype jceks

这样就成功了,密钥库里就添加了一条密钥

查看密钥库的条目:

E:\keytool>keytool -list -keystore cnivi.keystore -storetype jceks -v
输入密钥库口令:

密钥库类型: JCEKS
密钥库提供方: SunJCE

您的密钥库包含 1 个条目

别名: cnivi.seckey
创建日期: 2014-5-14
条目类型: SecretKeyEntry


*******************************************
*******************************************

Java代码:

@Test
public void test8776() throws Exception {

    String pass = "123456";
    String keypass = "034039";
    String name = "E:\\keytool\\cnivi.keystore";
    FileInputStream in = new FileInputStream(name);
    KeyStore ks = KeyStore.getInstance("JCEKS");
    ks.load(in, pass.toCharArray());
    Key secretkey = ks.getKey("cnivi.seckey", keypass.toCharArray());
    System.out.println(secretkey.toString());

    System.out.println("==================");

    KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) ks.getEntry("cnivi.seckey",
            new KeyStore.PasswordProtection(keypass.toCharArray()));

    SecretKey secretKey22 = secretKeyEntry.getSecretKey();

    System.out.println(secretKey22.toString());
}


密钥库类型

 Java默认的密钥库类型为JKS, 除这种类型外,还有PKCS12、JCEKS两种类型

要存储secret key要使用JCEKS类型,另外两种不支持。

JKS和JCEKS是Java密钥库(KeyStore)的两种比较常见类型(我所知道的共有5种,JKS, JCEKS, PKCS12, BKS,UBER)。

  1. JKS的Provider是SUN,在每个版本的JDK中都有。

  2. JCEKS的Provider是SUNJCE,1.4后我们都能够直接使用它。JCEKS在安全级别上要比JKS强,使用的Provider是JCEKS(推荐),尤其在保护KeyStore中的私钥上(使用TripleDes)。

  3. PKCS#12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 PFX 文件,在windows中可以直接导入到密钥区,注意,PKCS#12的密钥库保护密码同时也用于保护Key。

  4. BKS 来自BouncyCastle Provider,它使用的也是TripleDES来保护密钥库中的Key,它能够防止证书库被不小心修改(Keystore的keyentry改掉1个 bit都会产生错误),BKS能够跟JKS互操作,读者可以用Keytool去TryTry。

  5. UBER比较特别,当密码是通过命令行提供的时候,它只能跟keytool交互。整个keystore是通PBE/SHA1/Twofish加密,因此keystore能够防止被误改、察看以及校验。以前,Sun JDK(提供者为SUN)允许你在不提供密码的情况下直接加载一个Keystore,类似cacerts,UBER不允许这种情况

========END========

你可能感兴趣的:(Java密钥库类型JKS and JCEKS and PKCS12)