证书类型、自签CA证书、https双向认证(一篇就懂系列)
#博學(xué)谷IT學(xué)習(xí)技術(shù)支持#
文章目錄
- 1.Linux準(zhǔn)備環(huán)境
- 2.證書擴(kuò)展名
- 3.自簽CA證書
-
- 3.1 生成根證書
- 3.2 生成服務(wù)端證書
- 3.3 生成客戶端證書
- 4.開啟https,并校驗(yàn)客戶端(雙向認(rèn)證)
-
- 4.1配置nginx,開啟https
- 4.2開啟客戶端認(rèn)證
- 5.java代碼
最近在做接口對(duì)接的時(shí)候,需要雙方使用https協(xié)議以及客戶端認(rèn)證(https雙向認(rèn)證)。雖然之前接觸過https,了解一些https的原理以及加密算法,但是實(shí)際操作起來還是會(huì)多多少少的遇到一些問題。因此,將遇到的問題記錄下來,方便后續(xù)的閱讀和查找。也希望大家能夠更快的理解。
參考:
linux環(huán)境安裝nginx
pem和der文件擴(kuò)展名轉(zhuǎn)換
1.Linux準(zhǔn)備環(huán)境
- openssl
使用openssl version查看openssl版本,如果沒有安轉(zhuǎn)openssl,可以執(zhí)行 yum install openssl 安裝
- nginx
我們使用nginx來進(jìn)行https的雙向認(rèn)證,首先我們需要安裝nginx并附帶SSL 模塊
詳細(xì)的安裝過程可以查看 Linux安裝nginx ssl
2.證書擴(kuò)展名
在開發(fā)和測(cè)試階段,使用的是自簽的證書。在找自簽CA證書操作流程的時(shí)候,會(huì)有很多的文件擴(kuò)展名,如pem,der,csr.cer.crt.p12,pfx,jks等,剛開始接觸的話很容易混淆,因此先來看下證書的擴(kuò)展名。
- DER: .DER = DER擴(kuò)展用于二進(jìn)制DER編碼證書。這些文件也可能承載CER或CRT擴(kuò)展。
- PEM:使?Base64 ASCII進(jìn)?編碼的純?本格式,是以“ - BEGIN …”前綴的ASCII(Base64)數(shù)據(jù)。
- KEY:.KEY 擴(kuò)展名用于公鑰和私鑰,常見使用于私鑰。也可以被編碼為二進(jìn)制DER或ASCII PEM。
- CSR:證書簽名請(qǐng)求。CSR文件是申請(qǐng)SSL證書時(shí)所需要的一個(gè)數(shù)據(jù)文件。
- CRT:CRT擴(kuò)展用于證書。 證書可以被編碼為二進(jìn)制DER或ASCII PEM。 CER和CRT擴(kuò)展幾乎是同義詞。 最常見的于Unix 或類Unix系統(tǒng)。通俗來講,.CRT文件常在Linux系統(tǒng)使用,包含公鑰和主體信息。
- CER:.CRT的替代形式,您可以在微軟系統(tǒng)環(huán)境下將.CRT轉(zhuǎn)換為.CER(.both DER編碼的.CER,或base64 [PEM]編碼的.cer)。通俗來講,就是.CER擴(kuò)展文件是DER編碼,并且.CER文件常在Windows系統(tǒng)使用。
- P12:P12證書全稱是PKCS#12。是一種交換數(shù)字證書的加密標(biāo)準(zhǔn),用來描述個(gè)人身份信息。p12證書包含了私鑰、公鑰并且有口令保護(hù),在證書泄露后還有最后一道保障——證書口令,不知道正確的證書口令無法提取秘鑰(文件的擴(kuò)展名能夠?yàn)閜fx或p12)?
- PFX:PFX也是由PKCS#12標(biāo)準(zhǔn)定義,包含了公鑰和私鑰的二進(jìn)制格式的證書形式,以pfx做為證書文件后綴名(文件的擴(kuò)展名能夠?yàn)閜fx或p12)
- JKS:JKS是JAVA的keytools證書工具支持的證書私鑰格式
3.自簽CA證書
3.1 生成根證書
mkdir ssl 創(chuàng)建證書存放的?錄
cd ssl 進(jìn)?證書存放?錄
生成私鑰
openssl genrsa -out ca.key 2048 ?成根證書私鑰
查看一下ca.key 的內(nèi)容,可以看到
可以將ca.key轉(zhuǎn)為pem文件
openssl rsa -in ca.key -out ca-key.pem
再查看一下ca-key.pem文件,內(nèi)容和ca.key是相同的
生成根證書
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
-days設(shè)置證書有效時(shí)間,這里我們?cè)O(shè)置10年
生成證書時(shí)要輸入一些個(gè)體信息
證書生成后,可以查看ca.crt的內(nèi)容
也可以將ca.crt轉(zhuǎn)為pem文件
openssl x509 -in ca.crt -out ca-crt.pem
再查看一下ca-crt.pem文件,內(nèi)容和ca.crt是相同的
編碼類型轉(zhuǎn)換
PEM編碼轉(zhuǎn)為DER編碼 openssl x509 -in ca-crt.pem -outform der -out ca-crt.der
DER轉(zhuǎn)為PEM openssl x509 -in ca-crt.der -inform der -outform pem -out ca-crt.pem
(提示:要轉(zhuǎn)換KEY文件也類似)
der二進(jìn)制編碼的文件不能直接查看,可以使用命令查看.der文件
openssl x509 -in ca-crt.der -inform der -text -noout
3.2 生成服務(wù)端證書
為了便于理解和操作,這里統(tǒng)一使用pem編碼,并統(tǒng)一生成pem格式擴(kuò)展文件
生成服務(wù)端私鑰
生成pem擴(kuò)展名的私鑰
openssl genrsa -out server-key.pem 2048
2048表示生成的私鑰為2048位,一般使用2048位相對(duì)比較安全
將.pem擴(kuò)展名私鑰轉(zhuǎn)為.key
openssl rsa -in server-key.pem -out server.key
再查看server.key 和server.pem 私鑰內(nèi)容是相同的
生成服務(wù)端證書簽名請(qǐng)求文件
注意這?的common name必須是需要訪問的域名,其他的內(nèi)容可以和根證書填寫的?樣
openssl req -new -key server-key.pem -out server-csr.pem
可以將server-csr.pem轉(zhuǎn)為.csr擴(kuò)展名
openssl req -in server-csr.pem -out server.csr 或直接修改擴(kuò)展名 .pem為.csr
根據(jù)簽發(fā)請(qǐng)求?成服務(wù)端證書
openssl x509 -req -sha256 -in server-csr.pem -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server-crt.pem
可以將server-crt.pem轉(zhuǎn)為.crt擴(kuò)展名
openssl x509 -outform pem -in server-crt.pem -out server.crt
生成服務(wù)端pfx或p12證書
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx
注:在將.pem擴(kuò)展文件轉(zhuǎn)為key,csr,crt文件的時(shí)候,先查看文件內(nèi)容
包含 -----BEGIN RSA PRIVETE KEY ----- 的內(nèi)容可以導(dǎo)出轉(zhuǎn)換.key擴(kuò)展名的文件
包含 -----BEGIN CERTIFICATE REQUEST ----- 的內(nèi)容可以導(dǎo)出轉(zhuǎn)換.csr擴(kuò)展名的文件
包含 -----BEGIN CERTIFICATE ----- 的內(nèi)容可以導(dǎo)出轉(zhuǎn)換.crt擴(kuò)展名的文件
3.3 生成客戶端證書
客戶端證書?成步驟和服務(wù)端基本?樣,需要注意的就是在?成簽發(fā)請(qǐng)求的時(shí)候填寫的信息中,comm name也要是訪問的域名。
生成客戶端私鑰
openssl genrsa -out client.key 2048
生成客戶端證書簽名請(qǐng)求文件
openssl req -new -key client.key -out client.csr
根據(jù)簽發(fā)請(qǐng)求和?成客戶端證書
openssl x509 -req -sha256 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out client.crt
生成客戶端pfx或p12證書
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12
4.開啟https,并校驗(yàn)客戶端(雙向認(rèn)證)
4.1配置nginx,開啟https
- 開啟https請(qǐng)求
進(jìn)入nginx目錄,編輯nginx.conf – vim nginx.conf
找到HTTPS server
ssl_certificate 服務(wù)端crt證書路徑
ssl_certificatie_key 服務(wù)端私鑰路徑
配置完以后 啟動(dòng)或者容器一下nginx
啟動(dòng):在nginx目錄執(zhí)行 ./sbin/nginx
重啟:在nginx目錄執(zhí)行 ./sbin/nginx -s reload
在瀏覽器訪問是成功的,因?yàn)槲覀兪亲院炞C書,因此顯示不安全
4.2開啟客戶端認(rèn)證
vim nginx.conf繼續(xù)編輯nginx.conf
ssl_client_certificate 指定客戶端認(rèn)證時(shí)使?的根證書路徑,?來驗(yàn)證客戶端證書的正確性,我們使用的自簽ca證書簽發(fā)的客戶端證書,因此使用ca.crt
ssl_verify_client on 為開啟客戶端校驗(yàn)
配置完成后重啟nginx ./sbin/nginx -s reload
為了方便測(cè)試。我們直接使用curl 命令進(jìn)行測(cè)試
curl https://ip -k -v
ip為訪問的具體ip地址
-k編碼忽略服務(wù)端證書的校驗(yàn),因?yàn)槲覀冞@里服務(wù)端證書也是自簽的,所以要加上-k
不加-k,會(huì)有異常提示
-v為顯示具體的信息,也可以不加
使用上述命令訪問后
提示需要攜帶客戶端的證書,說明我們配置的客戶端認(rèn)證已經(jīng)生效了
curl --cert client.crt --key client.key https://ip -k
可以看到攜帶證書后訪問是成功的,說明客戶端已經(jīng)認(rèn)證成功了,因此https雙向認(rèn)證完成了
5.java代碼
附一段java代碼,代碼來自 https://wenku.baidu.com/view/ee8e04315c0e7cd184254b35eefdc8d376ee1494.html
public class SSLService {// 客戶端證書路徑,?了本地絕對(duì)路徑,需要修改private final static String CLIENT_CERT_FILE = "C:\\Users\\tzx\\Desktop\\client.p12";// 客戶端證書密碼private final static String CLIENT_PWD = "131112";// 信任庫(kù)路徑,即keytool?成的那個(gè)?定義名稱的庫(kù)?件private final static String TRUST_STRORE_FILE = "D:\\Java\\jdk1.8.0_131\\jre\\lib\\security\\test.truststore";// 信任庫(kù)密碼,即keytool時(shí)的密碼private final static String TRUST_STORE_PWD = "131112";private static String readResponseBody(InputStream inputStream) throws IOException {try {BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));StringBuffer sb = new StringBuffer();String buff = null;while ((buff = br.readLine()) != null) {sb.append(buff + "\n");}return sb.toString();} finally {inputStream.close();}}public static void httpsCall() throws Exception {// 初始化密鑰庫(kù)KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");KeyStore keyStore = getKeyStore(CLIENT_CERT_FILE, CLIENT_PWD, "PKCS12");keyManagerFactory.init(keyStore, CLIENT_PWD.toCharArray());// 初始化信任庫(kù)TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");KeyStore trustkeyStore = getKeyStore(TRUST_STRORE_FILE, TRUST_STORE_PWD, "JKS");trustManagerFactory.init(trustkeyStore);// 初始化SSL上下?SSLContext ctx = SSLContext.getInstance("SSL");ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);SSLSocketFactory sf = ctx.getSocketFactory();HttpsURLConnection.setDefaultSSLSocketFactory(sf);String url = "https://blog.tzx.com";URL urlObj = new URL(url);HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection();con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " +"(KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");con.setRequestProperty("Accept-Language", "zh-CN;en-US,en;q=0.5");con.setRequestMethod("GET");String res = readResponseBody(con.getInputStream());System.out.println(res);}/*** 獲得KeyStore*/private static KeyStore getKeyStore(String keyStorePath, String password, String type)throws Exception {FileInputStream is = new FileInputStream(keyStorePath);KeyStore ks = KeyStore.getInstance(type);ks.load(is, password.toCharArray());is.close();return ks;}public static void main(String[] args) throws Exception {httpsCall(null);}
}
總結(jié)
以上是生活随笔為你收集整理的证书类型、自签CA证书、https双向认证(一篇就懂系列)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Facebook iOS app中减少
- 下一篇: 苹果 iPhone 16 Pro 电池实