Java密钥库类型JKS and JCEKS and PKCS12
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.
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.
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 ******************************************* *******************************************
@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()); } }
-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)。
JKS的Provider是SUN,在每个版本的JDK中都有。
JCEKS的Provider是SUNJCE,1.4后我们都能够直接使用它。JCEKS在安全级别上要比JKS强,使用的Provider是JCEKS(推荐),尤其在保护KeyStore中的私钥上(使用TripleDes)。
PKCS#12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 PFX 文件,在windows中可以直接导入到密钥区,注意,PKCS#12的密钥库保护密码同时也用于保护Key。
BKS 来自BouncyCastle Provider,它使用的也是TripleDES来保护密钥库中的Key,它能够防止证书库被不小心修改(Keystore的keyentry改掉1个 bit都会产生错误),BKS能够跟JKS互操作,读者可以用Keytool去TryTry。
UBER比较特别,当密码是通过命令行提供的时候,它只能跟keytool交互。整个keystore是通PBE/SHA1/Twofish加密,因此keystore能够防止被误改、察看以及校验。以前,Sun JDK(提供者为SUN)允许你在不提供密码的情况下直接加载一个Keystore,类似cacerts,UBER不允许这种情况
========END========