Java不同类型密钥库之PKCS12和JCEKS

来源:互联网 发布:淘宝9月份活动 编辑:程序博客网 时间:2024/06/10 13:03

转:http://www.csdn.net/article/2015-01-06/2823434

Java不同类型密钥库之PKCS12和JCEKS

发表于2015-01-06 11:32|5234次阅读| 来源CSDN|9 条评论| 作者陈明

Java密钥库证书PKCS12JCEKS
摘要:密钥库是一个存放加密密钥和证书的存储设施,它们经常用于SSL通信来标明服务器和客户机的身份,本文所列的为Java密钥库中的PKCS12和JCEKS类型。介绍了其存储和加载密钥、证书所使用的代码片段。

编者注:密钥库是一个存放加密密钥和证书的存储设施,它们经常用于SSL通信来标明服务器和客户机的身份,一个密钥库可以是一份文件或硬件设备。Java中不同类型的密钥库包含:PrivateKey、SecretKey、JKS、PKCS12、JCEKS等。其中JKS的详细介绍可参考《Java不同密钥库类型之JKS》。本文所讲诉的为PKCS12和JCEKS的用法。

以下为译文:

JCEKS

JCEKS是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@fffe7b9b

PKCS12

PKCS12是公钥加密标准,它规定了可包含所有私钥、公钥和证书。其以二进制格式存储,也称为 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();}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 中通快递寄丢了怎么办 中通快递丢了怎么办 物流没保价坏了怎么办 顺丰保值快递丢了怎么办 顺丰保价件丢失怎么办 公司购买货物对方没有发票怎么办 加工货物对方不取怎么办 物流发货发错了怎么办 货车拉的货丢了怎么办 壹米滴答丢货怎么办 物流东西弄丢了怎么办 理赔款账号打错了怎么办 顺丰快递搞丢了怎么办 论文表格跨页了怎么办 网线突然没网了怎么办 室内门高门洞矮怎么办 路基填方土质含水率大怎么办 公路工程材料价格不予调差怎么办 桩基偏位60公分怎么办 定义的跨板受力筋长度不够怎么办 支座梁体预埋钢板忘记埋了怎么办 做nt小孩头朝下怎么办 简历上传的照片太大怎么办 本科毕业论文没写英文摘要怎么办 气泵储气罐有个小眼漏气怎么办 吸拉开关坏了怎么办 窗口数量已达上限怎么办 村土地原始台账没有怎么办 涂防晒霜后出汗怎么办 张拉千斤顶泄荷回油不到位怎么办 隧道二衬打到一半没混凝土怎么办 在左车道骑电动车撞到车怎么办 电镐钻头卡住了怎么办 玩具机器人无线遥控不了怎么办 电锤锤头卸不下来怎么办 打地基没打出硬土层怎么办 中标的项目经理没有B证怎么办 12306证件被注册过怎么办 政府3p项目不给钱怎么办 电气没考上国网怎么办 小区宽带业务被个人承包怎么办