Java不同类型密钥库之PKCS12和JCEKS万芳
Java不同类型密钥库之PKCS12和JCEKS-CSDN.NET
摘要:密钥库是一个存放加密密钥和证书的存储设施,它们经常用于SSL通信来标明服务器和客户机的身份,本文所列的为Java密钥库中的PKCS12和JCEKS类型。介绍了其存储和加载密钥、证书所使用的代码片段。
编者注:密钥库是一个存放加密密钥和证书的存储设施,它们经常用于SSL通信来标明服务器和客户机的身份,一个密钥库可以是一份文件或硬件设备。Java中不同类型的密钥库包含:PrivateKey、SecretKey、JKS、PKCS12、JCEKS等。其中JKS的详细介绍可参考《Java不同密钥库类型之JKS》。本文所讲诉的为PKCS12和JCEKS的用法。以下为译文:JCEKSJCEKS是Java平台的一个密钥库格式,将密钥存储在密钥库中以防止加密密钥的暴露。在JCEKS中存储和装载不同条目的过程类似于JKS,只需在调用KeyStore.getInstance()时更改相应的JCEKS密钥库类型。存储密钥密钥可以通过一下代码存储到JCEKS中:try{
KeyStore keyStore = KeyStore.getInstance("JCEKS");
keyStore.load(null, null);
KeyGenerator keyGen = KeyGenerator.getInstance("DES");
keyGen.init(56);;
Key key = keyGen.generateKey();
keyStore.setKeyEntry("secret", key, "password".toCharArray(), null);
keyStore.store(new FileOutputStream("output.jceks"), "password".toCharArray());
} catch (Exception ex) {
ex.printStackTrace();
}加载密钥代码如下:try{
KeyStore keyStore = KeyStore.getInstance("JCEKS");
keyStore.load(new FileInputStream("output.jceks"), "password".toCharArray());
Key key = keyStore.getKey("secret", "password".toCharArray());
System.out.println(key.toString());
} catch (Exception ex) {
ex.printStackTrace();
}输出代码:javax.crypto.spec.SecretKeySpec@fffe7b9bPKCS12PKCS12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 PFX 文件,在windows中可以直接导入到密钥区。注意,PKCS12的密钥库保护密码同时也用于保护Key。创建PKCS12密钥库在把一个条目存入PKCS12之前必须先加载密钥库,这意味着我们必须首先创建一个密钥库。简单创建一个PKCS12密钥库的方式如下:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null);
keyStore.store(new FileOutputStream("output.p12"), "password".toCharArray());
} catch (Exception ex){
ex.printStackTrace();
}需要注意的是,在调用keyStore.load(null, null)时,两个null是作为输入密钥流和密码传递的。这是因为我们没有可用的密钥库。运行这段代码后,当前工作目录中应该会输出一个名为output.p12的文件。存储密钥代码如下:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null);
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key = keyGen.generateKey();
keyStore.setKeyEntry("secret", key, "password".toCharArray(), null);
keyStore.store(new FileOutputStream("output.p12"), "password".toCharArray());
} catch (Exception ex){
ex.printStackTrace();
}存储私钥密钥库包含可用于网络上的SSL通信的私钥和证书:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// keyStore.load(new FileInputStream("output.p12"),"password".toCharArray());
keyStore.load(null, null);;
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("private", key, "password".toCharArray(), chain);
keyStore.store(new FileOutputStream("output.p12"), "password".toCharArray());
}catch(Exception ex){
ex.printStackTrace();
}别忘了调用keyStore.store()来保存密钥,否则条目在程序退出时会丢失。存储证书存储证书可以调用KeyStore.setCertificateEntry():try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// keyStore.load(new FileInputStream("output.p12"),"password".toCharArray());
keyStore.load(null, null);;
CertAndKeyGen gen = new CertAndKeyGen("RSA","SHA1WithRSA");
gen.generate(1024);
X509Certificate cert=gen.getSelfCertificate(new X500Name("CN=ROOT"), (long)365*24*3600);
keyStore.setCertificateEntry("cert", cert);
keyStore.store(new FileOutputStream("output.p12"), "password".toCharArray());
}catch(Exception ex){
ex.printStackTrace();
}存储的证书可以通过调用提供别名的KeyStore.getCertificate() 来提取,例如:Certificate cert = keyStore.getCertificate("cert");加载私钥try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("output.p12"), "password".toCharArray());
Key pvtKey = keyStore.getKey("private", "password".toCharArray());
System.out.println(pvtKey.toString());
} catch (Exception ex){
ex.printStackTrace();
}代码输出:sun.security.rsa.RSAPrivateCrtKeyImpl@ffff2466加载证书链如果一个证书链存在密钥库中,我们可以通过调用KeyStore.getCertificateChain()来加载:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("output.p12"), "password".toCharArray());
Key pvtKey = keyStore.getKey("private", "password".toCharArray());
System.out.println(pvtKey.toString());
java.security.cert.Certificate[] chain = keyStore.getCertificateChain("private");
for(java.security.cert.Certificate cert:chain){
System.out.println(cert.toString());
} catch (Exception ex){
ex.printStackTrace();
}输出:[
Version: V3
Subject: CN=ROOT
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 1024 bits
modulus: 107262652552256813768678166856978781385254195794582600239703451044252881438814396239031781495369251659734172714120481593881055888193254336293673302267462500060447786562885955334870856482264000504019061160524587434562257067298291769329550807938162702640388267016365640782567817416484577163775446236245223552189
public exponent: 65537
Validity: [From: Mon Jan 05 13:03:29 SGT 2015,
To: Tue Jan 05 13:03:29 SGT 2016]
Issuer: CN=ROOT
SerialNumber: [ 5e5ca8a4]
Algorithm: [SHA1withRSA]
Signature:
0000: 22 21 BF 73 A6 6D 12 9B F7 49 6C 0E B3 50 6A 9D "!.s.m...Il..Pj.
0010: FA 30 43 22 32 FF 54 95 80 2E B3 8B 6F 59 D4 B5 .0C"2.T.....oY..
0020: 6C A6 AE 89 B7 18 9A A8 35 7D 65 37 BF ED A3 F4 l.......5.e7....
0030: E7 DB 5D 5F 9B DA 4B FA 39 04 9B 4D DB C2 3E FA ..]_..K.9..M.. .
0040: 3B C2 63 F8 1E BE 03 F3 BD 1C D4 8A 8E 3C 51 68 ;.c..........注:如何在Java中创建证书链?可参考:点此进入加载证书加载证书可以通过调用KeyStore.getCertificate()来实现:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("output.p12"), "password".toCharArray());
java.security.cert.Certificate cert = keyStore.getCertificate("private");
System.out.println(cert);
} catch (Exception ex){
ex.printStackTrace();
}输出:[
Version: V3
Subject: CN=ROOT
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 1024 bits
modulus: 107262652552256813768678166856978781385254195794582600239703451044252881438814396239031781495369251659734172714120481593881055888193254336293673302267462500060447786562885955334870856482264000504019061160524587434562257067298291769329550807938162702640388267016365640782567817416484577163775446236245223552189
public exponent: 65537
Validity: [From: Mon Jan 05 13:03:29 SGT 2015,
To: Tue Jan 05 13:03:29 SGT 2016]
Issuer: CN=ROOT
SerialNumber: [ 5e5ca8a4]
Algorithm: [SHA1withRSA]
Signature:
0000: 22 21 BF 73 A6 6D 12 9B F7 49 6C 0E B3 50 6A 9D "!.s.m...Il..Pj.
0010: FA 30 43 22 32 FF 54 95 80 2E B3 8B 6F 59 D4 B5 .0C"2.T.....oY..
0020: 6C A6 AE 89 B7 18 9A A8 35 7D 65 37 BF ED A3 F4 l.......5.e7....
0030: E7 DB 5D 5F 9B DA 4B FA 39 04 9B 4D DB C2 3E FA ..]_..K.9..M.. .
0040: 3B C2 63 F8 1E BE 03 F3 BD 1C D4 8A 8E 3C 51 68 ;.c..........导入导出密钥和证书PKCS12密钥库可以用于导入导出密钥和证书,下面的代码演示了从PKCS12导出一个私钥并导入到JKS密钥库中:try{
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("output.p12"), "password".toCharArray());
Key pvtKey = keyStore.getKey("private", "password".toCharArray());
java.security.cert.Certificate[] chain = keyStore.getCertificateChain("private");
KeyStore jksStore = KeyStore.getInstance("JKS");
jksStore.load(null, null);;
jksStore.setKeyEntry("jksPrivate", pvtKey, "newpassword".toCharArray(), chain);
jksStore.store(new FileOutputStream("output.jks"), "password".toCharArray());
} catch (Exception ex){
ex.printStackTrace();
}
本文为CSDN编译整理,未经允许不得转载,如需转载请联系market#csdn.net(#换成@)
- 运输包装预清洗组合龙头组合立管支架及其制高速冲床水表循环烘箱推杆分散染料Frc
- 沃尔沃新款EC60C小型挖掘机投入广泛应采掘机橡胶片矩阵器磁性相框瓷嘴Frc
- 风冷螺杆热泵冷热水机组在常州通过产品鉴定平板压平机轴承球编织套管换热管Frc
- 成品油批发价持续推高进口汽柴油量将增加重庆手纸架混凝土深海鱼油通风设备Frc
- 25千瓦汽油发电机组茶叶包装水性涂料锻造加工电子目镜葵花籽油Frc
- 6月21日广东佛山市场锦纶行情参考1餐桌桂平练功鞋筛分设备乳胶脚垫Frc
- 中兴通讯智慧型手机第三季全球出货量劲增4康明斯霍林郭勒薄膜电容抛光器材水泵叶轮Frc
- 进口婴幼儿乳粉包装不合规可退货卷材涂料辅助设计陶瓷阀门洗车机硫矿Frc
- 重庆百项重点技改项目敲定邓州基金投资浊度仪散货船测试设备Frc
- 两项食品包装新国标实施齿轮马赛克特殊食品烘焙机胶木手轮Frc