阅读:
877
密钥库是用于存储加密密钥和证书的存储工具 ,最常用于SSL通信,以证明服务器和客户端的身份。密钥库可以是文件或硬件设备。有三种类型的条目可以存储在密钥库中,取决于密钥库的类型,这三种类型的条目分别是:
PrivateKey:用于非对称加密的密钥,通常由于其敏感性而受密码保护。它还可用于签署数字签名;
Certificate证书:证书包含一个公钥,可以识别证书中声明的主题 (Subject)。它通常用于验证服务器的身份。有时,它还用于在请求时识别客户端的身份,如双向认证时;
SecretKey:在对称加密中使用的密钥条目;
根据密钥库可以存储的条目以及密钥库如何存储条目,Java中有几种不同类型的密钥库:JKS,JCEKS,PKCS12,PKCS11和DKS。最常见的是JKS,JCEKS,PKCS12类型,我们将主要介绍这三种。可以在Oracle的Java Cryptography Architecture描述中找到这些密钥库的介绍。
接下来,我们将简要介绍这些密钥库类型:
JKS,Java
Key Store。可以参见sun.security.provider.JavaKeyStore类,此密钥库是特定于Java平台的,通常具有jks的扩展名。此类型的密钥库可以包含私钥和证书,但不能用于存储密钥。由于它是Java特定的密钥库,因此不能在其他编程语言中使用。存储在JKS中的私钥无法在Java中提取。
JCEKS,JCE密钥库(Java Cryptography
Extension KeyStore)。可以认为是增强式的JKS密钥库,支持更多算法。可以参考com.sun.crypto.provider.JceKeyStore类,此密钥库具有jceks的扩展名。可以放入JCEKS密钥库的条目是私钥,密钥和证书。此密钥库通过使用Triple DES加密为存储的私钥提供更强大的保护。
JCEKS的提供者是SunJCE,它是在Java 1.4中引入的。因此,在Java 1.4之前,只能使用JKS。
PKCS12,一种标准的密钥库类型,可以在Java和其他语言中使用。可以参考sun.security.pkcs12.PKCS12KeyStore类。它通常具有p12或pfx的扩展名。可以在此类型上存储私钥,密钥和证书。与JKS不同,PKCS12密钥库上的私钥可以用Java提取。此类型是可以与其他语言(如C,C
++或C#)编写的其他库一起使用。
目前,Java中的默认密钥库类型是JKS,即如果在使用keytool创建密钥库时未指定-storetype,则密钥库格式将为JKS。但是,默认密钥库类型将在Java 9中更改为PKCS12,因为与JKS相比,它具有增强的兼容性。可以在$ JRE / lib / security / java.security文件中检查默认密钥库类型。
PKCS11,一种硬件密钥库类型。 为Java库提供了一个接口,用于连接硬件密钥库设备,如智能卡。 可以参考sun.security.pkcs11.P11KeyStore类。 此密钥库可以存储私钥,密钥和证书。 加载密钥库时,将从密钥库中检索条目,然后将其转换为软件成勋可识别的条目;
BKS,BoucyCastle密钥库,是一种密钥库格式,提供了流行的第三方Java加密库提供程序–BouncyCastle。它是一个类似于Oracle JDK提供的JKS的密钥库。支持存储密钥,私钥和证书,经常用于移动应用程序开发。
在Java中,有一些关于如何处理密钥库的选择。编写Java代码是一种选择。除此之外,还可以使用JDK附带的工具keytool;
keytool是一个命令行工具。它可用于创建密钥库,生成密钥,导入和导出证书等。有关keytool支持的命令的完整列表,可以参考Oracle keytool准则;
如果使用的是IBM JDK,还有一个可以使用的工具,它是ikeyman。 ikeyman是一个GUI工具,可以提供密钥库的直观视图。密钥库中的条目。也可以使用ikeyman创建密钥和证书。它是系统管理员经常使用的工具。
JKS,Java
Key Store详细介绍
JKS是Java Keystore,一种专为Java设计的专有密钥库类型。 可以用于存储用于SSL通信的私钥和证书,但是它不能存储密钥。 JDK附带的keytool无法提取存储在JKS上的私钥。 这种类型的密钥库通常具有jks的扩展名。
接下来,将展示如何使用Java代码操作JKS密钥库;
创建JKS密钥库
创建JKS密钥库以创建空密钥库的最简单方法。 可以先获取KeyStore的实例,然后加载null密钥库。 加载null密钥库后,只需要使用密钥库的密钥库名称和密码调用KeyStore.store();
以下是一个简单的演示:
try{
KeyStore keyStore =
KeyStore.getInstance(“JKS”);
keyStore.load(null,null);
keyStore.store(new
FileOutputStream(“mytestkey.jks”),
“password”.toCharArray());
}catch(Exception
ex){
ex.printStackTrace();
}
执行上述调用后,将在当前工作目录中看到名为mytestkey.jks的密钥库。 现在该密钥库是空的,没有任何条目。
存储私钥
现在将一个私钥及其关联的证书链存储到密钥库中。 注意,无法使用JDK将没有关联证书链的私钥存储到密钥库中。
try{
KeyStore keyStore =
KeyStore.getInstance(“JKS”);
keyStore.load(new
FileInputStream(“mytestkey.jks”),”password”.toCharArray());
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.setKeyEntry(“mykey”,
key, “password”.toCharArray(), chain);
keyStore.store(new
FileOutputStream(“mytestkey.jks”),
“password”.toCharArray());
}catch(Exception
ex){
<