SSL/TLS協議運行機制

http://blog.csdn.net/fw0124/article/details/41013333html

 

關於SSL/TLS/JSSE的介紹:
1)SSL/TLS協議運行機制
2)圖解SSL/TLS協議
3)使用wireshark觀察SSL/TLS握手過程
4)SSL/TLS的Java實現--JSSEjava

(一)使用keytool建立密鑰庫

使用雙向認證的SSL/TLS協議通訊,客戶端和服務器端都要設置用於證明本身身份的安全證書,而且還要設置信任對方的哪些安全證書。
理論上一共須要準備四個文件,兩個keystore文件和兩個truststore文件。
通訊雙方分別擁有一個keystore和一個truststore,keystore用於存放本身的密鑰和公鑰,truststore用於存放全部須要信任方的公鑰。

首先使用JDK自帶的keytool工具來生成keystore和truststore。這裏使用的Java版本是1.7。
1)建立server的keystore文件,生成server的公鑰/私鑰密鑰對。須要指定keystore的密碼(storepass)和密鑰對的密碼(keypass)。
訪問keystore須要storepass。訪問密鑰對須要keypass。node

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -genkey -alias catserver -keyalg rsa -keysize 1024 -sigalg sha256withrsa -keypass catserver -keystore c:\_tmp\catserver.keystore -storepass catserverks  
  2. What is your first and last name?  
  3. [Unknown]: cat  
  4. What is the name of your organizational unit?  
  5. [Unknown]: cat  
  6. What is the name of your organization?  
  7. [Unknown]: cat  
  8. What is the name of your City or Locality?  
  9. [Unknown]: cat  
  10. What is the name of your State or Province?  
  11. [Unknown]: cat  
  12. What is the two-letter country code for this unit?  
  13. [Unknown]: ct  
  14. Is CN=cat, OU=cat, O=cat, L=cat, ST=cat, C=ct correct?  
  15. [no]: y</span>  


2)建立client的keystore文件。一樣須要指定keystore的密碼和密鑰對的密碼。linux

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -genkey -alias foxclient -keyalg dsa -keysize 512 -sigalg sha1withdsa -keypass foxclient -keystore c:\_tmp\foxclient.keystore -storepass foxclientks  
  2. What is your first and last name?  
  3. [Unknown]: fox  
  4. What is the name of your organizational unit?  
  5. [Unknown]: fox  
  6. What is the name of your organization?  
  7. [Unknown]: fox  
  8. What is the name of your City or Locality?  
  9. [Unknown]: fox  
  10. What is the name of your State or Province?  
  11. [Unknown]: fox  
  12. What is the two-letter country code for this unit?  
  13. [Unknown]: fx  
  14. Is CN=fox, OU=fox, O=fox, L=fox, ST=fox, C=fx correct?  
  15. [no]: y</span>  


3)從server的keystore中導出server的證書(其中包括server的公鑰)。算法

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -export -alias catserver -keystore c:\_tmp\catserver.keystore -storepass catserverks -file c:\_tmp\catserver.cer  
  2. Certificate stored in file <c:\_tmp\catserver.cer>  
  3. </span>  

4)從client的keystore中導出client的證書(其中包括client的公鑰)。編程

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -export -alias foxclient -keystore c:\_tmp\foxclient.keystore -storepass foxclientks -file c:\_tmp\foxclient.cer  
  2. Certificate stored in file <c:\_tmp\foxclient.cer>  
  3. </span>  


5)建立server的truststore文件並導入client的證書(其中包括client的公鑰)。安全

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -import -alias foxclient -keystore c:\_tmp\catservertrust.keystore -storepass catservertrustks -file c:\_tmp\foxclient.cer  
  2. Owner: CN=fox, OU=fox, O=fox, L=fox, ST=fox, C=fx  
  3. Issuer: CN=fox, OU=fox, O=fox, L=fox, ST=fox, C=fx  
  4. Serial number: 6eaf996f  
  5. Valid from: Wed Nov 05 16:15:41 CST 2014 until: Tue Feb 03 16:15:41 CST 2015  
  6. Certificate fingerprints:  
  7. MD5: B5:B6:92:66:84:92:A0:C2:F5:40:39:25:F8:66:2A:17  
  8. SHA1: 07:42:A3:1A:49:7B:C9:34:4B:6B:FA:37:6C:20:98:D4:20:13:7C:91  
  9. SHA256: 37:A5:00:A3:13:00:DE:99:3B:08:47:F6:1E:8A:05:F1:4A:B2:C6:22:20:  
  10. E1:AF:0E:05:B2:CE:E0:2F:94:B6:94  
  11. Signature algorithm name: SHA1withDSA  
  12. Version: 3  
  13.   
  14. Extensions:  
  15.   
  16. #1: ObjectId: 2.5.29.14 Criticality=false  
  17. SubjectKeyIdentifier [  
  18. KeyIdentifier [  
  19. 0000: 69 3E 6A D0 B5 B1 1F BD 48 46 E1 A4 6C 1F 71 90 i>j.....HF..l.q.  
  20. 0010: 29 06 3B 32 ).;2  
  21. ]  
  22. ]  
  23.   
  24. Trust this certificate? [no]: y  
  25. Certificate was added to keystore</span>  


6)建立client的truststore文件並導入server的證書(其中包括server的公鑰)。bash

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">C:\Program Files\Java\jre7\bin>keytool -import -alias catserver -keystore c:\_tmp\foxclienttrust.keystore -storepass foxclienttrustks -file c:\_tmp\catserver.cer  
  2. Owner: CN=cat, OU=cat, O=cat, L=cat, ST=cat, C=ct  
  3. Issuer: CN=cat, OU=cat, O=cat, L=cat, ST=cat, C=ct  
  4. Serial number: 3e421457  
  5. Valid from: Wed Nov 05 16:13:52 CST 2014 until: Tue Feb 03 16:13:52 CST 2015  
  6. Certificate fingerprints:  
  7. MD5: 20:44:7C:E5:30:E6:7A:21:C2:49:64:77:E1:3A:A0:77  
  8. SHA1: 8B:02:D2:BE:98:2F:99:94:08:47:E2:96:EC:05:1B:5D:B1:8F:30:2F  
  9. SHA256: A6:66:85:F4:C2:B2:06:4E:2E:40:D8:52:84:6E:85:2B:5B:BB:C3:B0:9C:  
  10. 31:92:99:F5:91:5D:83:67:C8:4D:D8  
  11. Signature algorithm name: SHA256withRSA  
  12. Version: 3  
  13.   
  14. Extensions:  
  15.   
  16. #1: ObjectId: 2.5.29.14 Criticality=false  
  17. SubjectKeyIdentifier [  
  18. KeyIdentifier [  
  19. 0000: F5 91 E6 14 EE EF 5F 24 4F AC 6F A6 B8 36 A6 11 ......_$O.o..6..  
  20. 0010: 2B 5C DF 04 +\..  
  21. ]  
  22. ]  
  23.   
  24. Trust this certificate? [no]: y  
  25. Certificate was added to keystore</span>  


keysize
若是加密算法是rsa,key size範圍512->16384 bits,而且必須是64的倍數。
若是加密算法是dsa,key size範圍512->1024 bits,而且必須是64的倍數。

sigalg
若是加密算法是rsa,簽名算法能夠是md5withrsa/sha1withrsa/sha256withrsa/sha384withrsa/sha512withrsa
若是加密算法是dsa,簽名算法能夠是sha1withdsa

若是熟悉Java的socket編程,就會發現使用JSSE進行SSL/TLS編程其實和它很類似。
區別在於ServerSocket對象換成了SSLServerSocket,Socket對象換成了SSLSocket對象。服務器

(二)server端處理流程和代碼

處理流程:
1)加載server的keystore文件,須要指定keystore的密碼(storepass)。
KeyStore類型有以下三種: 
jceks - The proprietary keystore implementation provided by the SunJCE provider. 
jks - The proprietary keystore implementation provided by the SUN provider. 
pkcs12 - The transfer syntax for personal identity information as defined in PKCS #12.

2)加載server的truststore文件,須要指定truststore的密碼(storepass)。

3) 建立KeyManagerFactory對象並用1)中加載的keystore和server密鑰對的密碼(keypass)來初始化。

4) 建立TrustManagerFactory對象並用2)中加載的truststore來初始化。truststore中存的是client的公鑰,不須要keypass也能夠訪問。

5)建立SSLContext並用3)和4)中建立的KeyManagerFactory和TrustManagerFactory對象來初始化。
http://docs.Oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext
建立SSLContext是須要給出SSLContext Algorithms。上面這個連接中給出了合法的SSLContext Algorithms,有以下可用值。
SSL - Supports some version of SSL; may support other versions 
SSLv2 - Supports SSL version 2 or later; may support other versions 
SSLv3 - Supports SSL version 3; may support other versions 
TLS - Supports some version of TLS; may support other versions 
TLSv1 - Supports RFC 2246: TLS version 1.0 ; may support other versions 
TLSv1.1 - Supports RFC 4346: TLS version 1.1 ; may support other versions 
TLSv1.2 - Supports RFC 5246: TLS version 1.2 ; may support other versions 

6)建立SSLServerSocketFactory,在指定的端口上建立SSLServerSocket並設定須要客戶端證書:setNeedClientAuth(true)

7)在SSLServerSocket對象上調用accept()方法等待客戶端的鏈接。
客戶端連上來以後這個函數會返回一個SSLSocket對象,在這個對象的輸入輸出流上進行讀寫。
在這個SSLSocket對象上能夠添加一個HandshakeCompletedListener的監聽器,SSL/TLS握手結束後這個監聽器的handshakeCompleted方法就會被調用。
客戶端有三種方法會觸發握手:
- 顯式調用startHandshake方法/calling startHandshake which explicitly begins handshakes, or
- 在socket對象上進行read或write操做/any attempt to read or write application data on this socket causes an implicit handshake, or
- 在socket對象上調用getSession方法/a call to getSession tries to set up a session if there is no currently valid session, and an implicit handshake is done.網絡

[java]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">package learning.net.ssl;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.FileInputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.io.PrintWriter;  
  8. import java.net.Socket;  
  9. import java.security.KeyStore;  
  10. import java.security.cert.X509Certificate;  
  11.   
  12. import javax.net.ssl.HandshakeCompletedEvent;  
  13. import javax.net.ssl.HandshakeCompletedListener;  
  14. import javax.net.ssl.KeyManagerFactory;  
  15. import javax.net.ssl.SSLContext;  
  16. import javax.net.ssl.SSLPeerUnverifiedException;  
  17. import javax.net.ssl.SSLServerSocket;  
  18. import javax.net.ssl.SSLServerSocketFactory;  
  19. import javax.net.ssl.SSLSocket;  
  20. import javax.net.ssl.TrustManagerFactory;  
  21.   
  22. public class CatServer implements Runnable, HandshakeCompletedListener {  
  23.   
  24.     public static final int SERVER_PORT = 11123;  
  25.   
  26.     private final Socket _s;  
  27.     private String peerCerName;  
  28.   
  29.     public CatServer(Socket s) {  
  30.         _s = s;  
  31.     }  
  32.   
  33.     public static void main(String[] args) throws Exception {  
  34.         String serverKeyStoreFile = "c:\\_tmp\\catserver.keystore";  
  35.         String serverKeyStorePwd = "catserverks";  
  36.         String catServerKeyPwd = "catserver";  
  37.         String serverTrustKeyStoreFile = "c:\\_tmp\\catservertrust.keystore";  
  38.         String serverTrustKeyStorePwd = "catservertrustks";  
  39.   
  40.         KeyStore serverKeyStore = KeyStore.getInstance("JKS");  
  41.         serverKeyStore.load(new FileInputStream(serverKeyStoreFile), serverKeyStorePwd.toCharArray());  
  42.   
  43.         KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS");  
  44.         serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray());  
  45.   
  46.         KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  47.         kmf.init(serverKeyStore, catServerKeyPwd.toCharArray());  
  48.   
  49.         TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
  50.         tmf.init(serverTrustKeyStore);  
  51.   
  52.         SSLContext sslContext = SSLContext.getInstance("TLSv1");  
  53.         sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  
  54.   
  55.         SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();  
  56.         SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(SERVER_PORT);  
  57.         sslServerSocket.setNeedClientAuth(true);  
  58.   
  59.         while (true) {  
  60.             SSLSocket s = (SSLSocket)sslServerSocket.accept();  
  61.             CatServer cs = new CatServer(s);  
  62.             s.addHandshakeCompletedListener(cs);  
  63.             new Thread(cs).start();  
  64.         }  
  65.     }  
  66.   
  67.     @Override  
  68.     public void run() {  
  69.         try {  
  70.             BufferedReader reader = new BufferedReader(new InputStreamReader(_s.getInputStream()));  
  71.             PrintWriter writer = new PrintWriter(_s.getOutputStream(), true);  
  72.   
  73.             writer.println("Welcome~, enter exit to leave.");  
  74.             String s;  
  75.             while ((s = reader.readLine()) != null && !s.trim().equalsIgnoreCase("exit")) {  
  76.                 writer.println("Echo: " + s);  
  77.             }  
  78.             writer.println("Bye~, " + peerCerName);  
  79.         } catch (Exception e) {  
  80.             e.printStackTrace();  
  81.         } finally {  
  82.             try {  
  83.                 _s.close();  
  84.             } catch (IOException e) {  
  85.                 e.printStackTrace();  
  86.             }  
  87.         }  
  88.     }  
  89.   
  90.     @Override  
  91.     public void handshakeCompleted(HandshakeCompletedEvent event) {  
  92.         try {  
  93.             X509Certificate cert = (X509Certificate) event.getPeerCertificates()[0];  
  94.             peerCerName = cert.getSubjectX500Principal().getName();  
  95.         } catch (SSLPeerUnverifiedException ex) {  
  96.             ex.printStackTrace();  
  97.         }  
  98.     }  
  99.   
  100. }</span>  

(三)client端處理流程和代碼

處理流程:(1~5和server相同)
1)加載client的keystore文件。

2)加載client的truststore文件。

3) 建立KeyManagerFactory對象並初始化。

4) 建立TrustManagerFactory對象並初始化。truststore中存的是server的公鑰,不須要keypass也能夠訪問。

5)建立SSLContext並用3)和4)中建立的KeyManagerFactory和TrustManagerFactory對象來初始化。

6)建立SSLSocketFactory,在指定的網絡地址和端口上建立SSLSocket。

7)在這個SSLSocket對象的輸入輸出流上進行讀寫。

[java]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. <span style="font-family:Verdana;">package learning.net.ssl;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.FileInputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.io.PrintWriter;  
  8. import java.net.Socket;  
  9. import java.security.KeyStore;  
  10.   
  11. import javax.net.ssl.KeyManagerFactory;  
  12. import javax.net.ssl.SSLContext;  
  13. import javax.net.ssl.SSLSocketFactory;  
  14. import javax.net.ssl.TrustManagerFactory;  
  15.   
  16. public class FoxClient {  
  17.     public static void main(String[] args) throws Exception {  
  18.         String clientKeyStoreFile = "c:\\_tmp\\foxclient.keystore";  
  19.         String clientKeyStorePwd = "foxclientks";  
  20.         String foxclientKeyPwd = "foxclient";  
  21.         String clientTrustKeyStoreFile = "c:\\_tmp\\foxclienttrust.keystore";  
  22.         String clientTrustKeyStorePwd = "foxclienttrustks";  
  23.   
  24.         KeyStore clientKeyStore = KeyStore.getInstance("JKS");  
  25.         clientKeyStore.load(new FileInputStream(clientKeyStoreFile), clientKeyStorePwd.toCharArray());  
  26.   
  27.         KeyStore clientTrustKeyStore = KeyStore.getInstance("JKS");  
  28.         clientTrustKeyStore.load(new FileInputStream(clientTrustKeyStoreFile), clientTrustKeyStorePwd.toCharArray());  
  29.   
  30.         KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
  31.         kmf.init(clientKeyStore, foxclientKeyPwd.toCharArray());  
  32.   
  33.         TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
  34.         tmf.init(clientTrustKeyStore);  
  35.   
  36.         SSLContext sslContext = SSLContext.getInstance("TLSv1");  
  37.         sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  
  38.           
  39.         SSLSocketFactory socketFactory = sslContext.getSocketFactory();  
  40.         Socket socket = socketFactory.createSocket("localhost", CatServer.SERVER_PORT);  
  41.           
  42.         PrintWriter out = new PrintWriter(socket.getOutputStream(), true);  
  43.         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  44.           
  45.         send("hello", out);  
  46.         send("exit", out);  
  47.         receive(in);  
  48.         socket.close();  
  49.     }  
  50.       
  51.     public static void send(String s, PrintWriter out) throws IOException {  
  52.         System.out.println("Sending: " + s);       
  53.         out.println(s);  
  54.     }  
  55.   
  56.     public static void receive(BufferedReader in) throws IOException {  
  57.         String s;  
  58.         while ((s = in.readLine()) != null) {  
  59.             System.out.println("Reveived: " + s);  
  60.         }  
  61.     }  
  62. }</span>  

 

 

(四)使用Openssl進行證書籤名

若是須要對證書進行簽名,可使用keytool生成一個csr(certificate sign request), 而後提交到一個CA進行簽名。這裏使用openssl提供的CA功能。

 

1)[openssl]生成CA的RSA私鑰。
bash-3.00$ openssl genrsa -out cakey.pem 1024

2)[openssl]使用CA.sh腳本初始化CA。腳本會要求輸入剛纔生成的私鑰文件。
bash-3.00$ CA.sh -newca
CA certificate filename (or enter to create)
cakey.pem

3)[openssl]利用CA私鑰生成自簽名的CA根證書。
指定x509參數表示要生成自簽名的證書。(咱們知道證書裏面只包含公鑰,爲何從私鑰能夠生成證書呢?這是由於私鑰裏面包含RSA算法所需的參數,其實能夠算出公鑰,後面會詳細解釋)
bash-3.00$ openssl req -new -x509 -key cakey.pem -out ca.cer -config openssl.cnf
Linux上openssl.cnf的路徑/etc/pki/tls/openssl.cnf,能夠拷貝一份到當前目錄)

4)[keytool]生成server的keystore文件。
C:\Program Files\Java\jre7>keytool -genkey -alias catserver -keyalg rsa -keysize 1024 -sigalg sha256withrsa -keypass catserver -keystore c:\_tmp\catserver.keystore -storepass catserverks

5)[keytool]生成server的csr.
C:\Program Files\Java\jre7>keytool -certreq -alias catserver -file c:\_tmp\catserver.csr -keypass catserver -keystore c:\_tmp\catserver.keystore -storepass catserverks

6) [openssl]對server的csr進行簽名獲得server證書
bash-3.00$ openssl ca -in catserver.csr -out catserver.cer -cert ca.cer -keyfile cakey.pem -config openssl.cnf
(若是是由於權限問題,不能訪問CA的newcerts目錄,能夠先進行以下操做:
bash-3.00$ mkdir newcerts 
bash-3.00$ touch index.txt 
bash-3.00$ echo 01 > serial)

7)[keytool]生成client的keystore文件
C:\Program Files\Java\jre7>keytool -genkey -alias foxclient -keyalg dsa -keysize 512 -sigalg sha1withdsa -keypass foxclient -keystore c:\_tmp\foxclient.keystore -storepass foxclientks

8)[keytool]生成client的csr.
C:\Program Files\Java\jre7>keytool -certreq -alias foxclient -file c:\_tmp\foxclient.csr -keypass foxclient -keystore c:\_tmp\foxclient.keystore -storepass foxclientks

9) [openssl]對client的csr進行簽名獲得client證書
bash-3.00$ openssl ca -in foxclient.csr -out foxclient.cer -cert ca.cer -keyfile cakey.pem -config openssl.cnf

如今咱們有以下文件:
catserver.keystore -- server的keystore文件
catserver.cer -- server證書文件,已經由CA簽名。

foxclient.keystore -- client的keystore文件
foxclient.cer -- client證書文件,已經由CA簽名。

ca.cer -- CA的證書文件。做爲根證書。

接下來咱們還須要
10)[keytool]導入ca.cer和catserver.cer到catserver.keystore
keytool -import -trustcacerts -alias ca -keystore c:\_tmp\catserver.keystore -storepass catserverks -file c:\_tmp\ca.cer
keytool -import -alias catserver -keypass catserver -keystore c:\_tmp\catserver.keystore -storepass catserverks -file c:\_tmp\catserver.cer

11)[keytool]導入ca.cer和foxclient.cer到foxclient.keystore
keytool -import -trustcacerts -alias ca -keystore c:\_tmp\foxclient.keystore -storepass foxclientks -file c:\_tmp\ca.cer
keytool -import -alias foxclient -keypass foxclient -keystore c:\_tmp\foxclient.keystore -storepass foxclientks -file c:\_tmp\foxclient.cer

12)[keytool]建立server的truststore文件並導入ca.cer和foxclient.cer.
keytool -import -trustcacerts -alias ca -keystore c:\_tmp\catservertrust.keystore -storepass catservertrustks -file c:\_tmp\ca.cer
keytool -import -alias foxclient -keystore c:\_tmp\catservertrust.keystore -storepass catservertrustks -file c:\_tmp\foxclient.cer

13)[keytool]建立client的truststore文件並導入ca.cer和catserver.cer.
keytool -import -trustcacerts -alias ca -keystore c:\_tmp\foxclienttrust.keystore -storepass foxclienttrustks -file c:\_tmp\ca.cer
keytool -import -alias catserver -keystore c:\_tmp\foxclienttrust.keystore -storepass foxclienttrustks -file c:\_tmp\catserver.cer

 

*前面提到能夠從CA的私鑰文件生成CA的根證書。證書裏面其實包含的是公鑰。
其實openssl也提供命令能夠直接從私鑰cakey.pem生成公鑰。
openssl rsa -in cakey.pem -pubout -out caputkey.pem
爲何可以從私鑰推導出公鑰呢?
這須要瞭解RSA算法-〉http://blog.csdn.NET/fw0124/article/details/41118525
緣由很簡單,由於私鑰中也包含了計算公鑰所需的參數n和e。

*可使用openssl來生成server的證書,步驟以下
openssl genrsa -out catserverkey.pem 1024
openssl req -new -key catserverkey.pem -out catserver.csr -config openssl.cnf
openssl ca -in catserver.csr -out catserver.cer -cert ca.cer -keyfile cakey.pem -config openssl.cnf

=====================================

若是openssl ca ...進行簽名的時候碰到
The stateOrProvinceName field needed to be the same in the ...的錯誤,能夠修改openssl.cnf文件:
[ policy_match ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional

若是遇到
failed to update database
TXT_DB error number 2     的錯誤,
刪除index.txt,並再touch下

 

若是keytool -import命令導入簽名後的證書的時候遇到如下錯誤
keytool 錯誤: java.lang.Exception: 沒法從回覆中創建鏈
從新導入下ca.cer便可。
keytool -delete -alias ca -keystore c:\_tmp\catserver.keystore -storepass catserverks
keytool -import -trustcacerts -alias ca ...

======================================

 

CER文件到PEM文件的轉換較簡單。這二者都是X509證書,編碼不一樣,使用openssl工具便可:

openssl x509 -inform der -in catserver.cer -out catserver.pem

 

 

(五)如何從.keystore文件中導出私鑰

Keytool不支持直接從.keystore中導出私鑰。可是能夠把JKS文件轉換成openssl支持的PKCS#12格式的文件。

 

因此能夠經過下面2步來從.keystore中導出私鑰。

➜ ~ keytool -importkeystore -srckeystore catserver.keystore -destkeystore catserver.p12 -deststoretype PKCS12 -srcalias catserver -srcstorepass catserverks -srckeypass catserver -deststorepass catserverks -destkeypass catserver
Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -destkeypass value.
➜  ~  openssl pkcs12 -in catserver.p12  -nodes -nocerts -out catserverkey.pem
Enter Import Password:
MAC verified OK
➜  ~

*-nodes選項意思是No DES,即不加密導出的私鑰。

相關文章
相關標籤/搜索