Java密鑰庫的不同類型 -- PKCS12


原文:https://www.pixelstech.net/article/1420427307-Different-types-of-keystore-in-Java----PKCS12

轉載:https://www.cnblogs.com/yangchongxing/p/13837017.html

Different types of keystore in Java -- PKCS12

Java密鑰庫的不同類型 -- PKCS12

JKCS12 is an active file format for storing cryptography objects as a single file. It can be used to store secret key, private key and certificate.It is a standardized format published by RSA Laboratories which means it can be used not only in Java but also in other libraries in C, C++ or C# etc. This file format is frequently used to import and export entries from or to other keystore types.

JKCS12是一種活動文件格式,用於將加密對象存儲為單個文件。它可以用來存儲密鑰、私鑰和證書。它是RSA實驗室發布的標准格式,它不僅可以用於java,而且可以用於C、C++或C等的其他庫。這種文件格式經常用於從和向其他密鑰存儲類型導入和導出條目。

Next we will explain the operations which can be performed on PKCS12 keystore.

接下來我們將解釋可以在PKCS12密鑰庫上執行的操作。

Create PKCS12 keystore

創建PKCS12密鑰庫

Before storing an entry into a PKCS12 keystore, the keystore has to be loaded first. This means we have to have a keystore created first. The simplest way of creating a PKCS12 keystore is :

在將條目存儲到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();
}

Note, when calling keyStore.load(null, null), two nulls are passed as the input keystore stream and password. This is because we don't have the keystore available yet. After running this program, there should be a keystore file named output.p12 in current working directory.

注意,當調用keyStore.load(null, null),傳遞兩個null作為輸入密鑰庫流和密碼。這是因為我們還沒有密鑰庫。運行此程序后,當前工作目錄中應該有一個名為output.p12的密鑰庫文件。

Store secret key

存儲密鑰

PKCS12 allows to store secret keys on a limited base. Secret keys are frequently used to encrypt/decrypt data. To transfer the keys conveniently, they can be stored in a keystore like PKCS12 and transferred.

PKCS12允許在有限的基礎上存儲密鑰。密鑰經常用於加密/解密數據。為了方便地傳輸密鑰,可以將它們存儲在PKCS12這樣的密鑰庫中並進行傳輸。

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();
}

Some secret keys with algorithm AES stored on PKCS12 keystore cannot be extracted in Java. Since PKCS12 is a portable standard, other libraries may support extracting secret keys.

在Java中無法提取PKCS12密鑰庫中存儲的具有AES算法的密鑰。由於PKCS12是一個可移植的標准,其他庫可能支持提取密鑰。

Store private key

存儲私鑰

The private key and its associated certificate chain can be stored in PKCS12 keystore. The keystore contains private keys and certificates can be used in SSL communications across the web.

私鑰及其關聯的證書鏈可以存儲在PKCS12密鑰庫中。密鑰庫包含私鑰,證書可用於跨web的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();
}

A RSA private key is generated with the CertAndKeyGen and the associated certificate is also generated. Then the key entry is stored in the keyStore by calling keyStore.setEntry(). Don't forget to save the keyStore by calling keyStore.store(), otherwise the entry will be lost when the program exits.

使用CertAndKeyGen生成RSA私鑰,並生成相關證書。然后調用keyStore.setEntry()把私鑰條目存入密鑰庫. 別忘了調用keyStore.store(),否則當程序退出時條目將丟失。

Store certificate

存儲證書

PKCS12 keystore also allows to store certificate by itself without the corresponding private key stored. To store the certificate, the KeyStore.setCertificateEntry() can be called.

PKCS12密鑰庫還允許在不存儲相應私鑰的情況下單獨存儲證書。存儲證書調用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();
}

The stored certificate can be extracted by calling KeyStore.getCertificate() with the supplied alias. For example :

存儲的證書可以通過別名調用KeyStore.getCertificate()提取。例如:

Certificate cert = keyStore.getCertificate("cert");

Load private key

加載私鑰

One difference between PKCS12 keystore and other keystores such as JKS is that PKCS12's private key can be extracted without NullPointerException. The private key can be correctly extracted with the correct password provided.

PKCS12密鑰庫與其他密鑰庫(如JKS)的一個區別是,PKCS12的私鑰可以在沒有空指針異常的情況下提取。使用正確密碼可以正確提取私鑰。

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();
}

The output of the above code is:

上述代碼的輸出為:

sun.security.rsa.RSAPrivateCrtKeyImpl@ffff2466

Load certificate chain

加載證書鏈

If a certificate chain is stored in a keystore, it can be loaded by calling KeyStore.getCertificateChain(). Below code is used to extract the associated certificate chain for the associated private key.

如果一個證書鏈存儲在密鑰庫中,則可以通過調用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();
}

The output is :

[
[
  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..........

Load certificate

加載證書

Loading certificate is simple as well by calling KeyStore.getCertificate(), if the alias supplied is mapping to a certificate chain, only the leaf certificate will be returned.

加載證書也很簡單,通過調用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();
}

The output looks like:

[
[
  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..........

Import and export keys and certificates

導入和導出密鑰和證書

The PKCS12 keystore can be used to import and export keys and certificates. Since private keys can be extracted from PKCS12 keystores, so the entries can be exported from PKCS12 keystore and then be imported to other keystore types such as JKS.

PKCS12密鑰庫可用於導入和導出密鑰和證書。由於私鑰可以從PKCS12 keystore中提取,因此可以從PKCS12 keystore導出條目,然后導入到其他keystore類型,如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();
}

PKCS12 keystore is the recommended keystore type if you want to have a portable keystore type and you may want to use it with other non-Java libraries in the future.

如果您希望擁有可移植的密鑰庫類型,並且將來可能希望將其與其他非Java庫一起使用,那么PKCS12 keystore是推薦的keystore類型。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM