科普:TLS、SSL、HTTPS以及证书(转)
最近在研究基于ssl的傳輸加密,涉及到了key和證書相關(guān)的話題,走了不少?gòu)澛?#xff0c;現(xiàn)在總結(jié)一下做個(gè)備忘
?
不少人可能聽過其中的超過3個(gè)名詞,但它們究竟有什么關(guān)聯(lián)呢?
- TLS是 傳輸層安全協(xié)議(Transport Layer Security)的縮寫,是一種對(duì)基于網(wǎng)絡(luò)的傳輸?shù)募用軈f(xié)議,可以在受信任的第三方公證基礎(chǔ)上做雙方的身份認(rèn)證。TLS可以用在TCP上,也可以用在無(wú) 連接的UDP報(bào)文上。協(xié)議規(guī)定了身份認(rèn)證、算法協(xié)商、密鑰交換等的實(shí)現(xiàn)。
- SSL是TLS的前身,現(xiàn)在已不再更新
- HTTPS是在基于TLS/SSL的安全套接字上的的應(yīng)用層協(xié)議,除了傳輸層進(jìn)行了加密外,其它與常規(guī)HTTP協(xié)議基本保持一致
- 證書是TLS協(xié)議中用來(lái)對(duì)身份進(jìn)行驗(yàn)證的機(jī)制,是一種數(shù)字簽名形式的文件,包含證書擁有者的公鑰及第三方的證書信息。
證書分為2類:自簽名證書和CA證書。一般自簽名證書不能用來(lái)進(jìn)行身份認(rèn)證,如果一個(gè)server端使用自簽名證書,client端要么被設(shè)置為無(wú)條件信任任何證書,要么需要將自簽名證書的公鑰和私鑰加入受信任列表。但這樣一來(lái)就增加了server的私鑰泄露風(fēng)險(xiǎn)。
TLS基于CA的身份認(rèn)證基本原理是:首先驗(yàn)證方需要信任CA提供方自己的證書(CAcert),比如證書在操作系統(tǒng)的受信任證書列表中,或者用戶 通過“安裝根證書”等方式將 CA的公鑰和私鑰加入受信任列表;然后CA對(duì)被驗(yàn)證方的原始證書進(jìn)行簽名(私鑰加密),生成最終的證書;驗(yàn)證方得到最終的證書后,利用CAcert中包含 的公鑰進(jìn)行解密,得到被驗(yàn)證方的原始證書。
根據(jù)RSA的加密原理,如果用CA的公鑰解密成功,說(shuō)明該證書的確是用CA的私鑰加密的,可以認(rèn)為被驗(yàn)證方是可信的。
下面我們以客戶端單方對(duì)服務(wù)器端進(jìn)行身份認(rèn)證場(chǎng)景,來(lái)講解如何做證書的生成。
證書的生成
證書的生成可以用linux的OpenSSL工具鏈。對(duì)于一個(gè)網(wǎng)站,首先必須有自己的私鑰,私鑰的生成方式為:
openssl genrsa -out ssl.key 2048私鑰必須妥善保管,既不能丟失,也不能泄露。如果發(fā)生丟失和泄露,必須馬上重新生成,以使舊的證書失效。
如果要對(duì)私鑰進(jìn)行傳輸/備份,建議先對(duì)私鑰進(jìn)行密碼加密:
openssl rsa -in ssl.key -des3 -out encrypted.key利用私鑰就可以生成證書了。OpenSSL使用x509命令生成證書。這里需要區(qū)分兩個(gè)概念:證書(certificate)和證書請(qǐng)求(certificate sign request)
- 證書是自簽名或CA簽名過的憑據(jù),用來(lái)進(jìn)行身份認(rèn)證
- 證書請(qǐng)求是對(duì)簽名的請(qǐng)求,需要使用私鑰進(jìn)行簽名
x509命令可以將證書和證書請(qǐng)求相互轉(zhuǎn)換,不過我們這里只用到從證書請(qǐng)求到證書的過程
從私鑰或已加密的私鑰均可以生成證書請(qǐng)求。生成證書請(qǐng)求的方法為:
openssl req -new -key ssl.key -out ssl.csr如果私鑰已加密,需要輸入密碼。req命令會(huì)通過命令行要求用戶輸入國(guó)家、地區(qū)、組織等信息,這些信息會(huì)附加在證書中展示給連接方。
接下來(lái)用私鑰對(duì)證書請(qǐng)求進(jìn)行簽名。根據(jù)不同的場(chǎng)景,簽名的方式也略有不同
自簽名,生成私有證書
自簽名的原理是用私鑰對(duì)該私鑰生成的證書請(qǐng)求進(jìn)行簽名,生成證書文件。該證書的簽發(fā)者就是自己,所以驗(yàn)證方必須有該證書的私鑰才能對(duì)簽發(fā)信息進(jìn)行驗(yàn) 證,所以要么驗(yàn)證方信任一切證書,面臨冒名頂替的風(fēng)險(xiǎn),要么被驗(yàn)證方的私鑰(或加密過的私鑰)需要發(fā)送到驗(yàn)證方手中,面臨私鑰泄露的風(fēng)險(xiǎn)。
當(dāng)然自簽名也不是一無(wú)用處,比如需要內(nèi)部通訊的兩臺(tái)電腦需要使用加密又不想用第三方證書,可以在兩端使用相同的私鑰和證書進(jìn)行驗(yàn)證(當(dāng)然這樣就跟對(duì)稱加密沒有區(qū)別了)
自簽名的方法為:
openssl x509 -req -in ssl.csr -signkey ssl.key -out ssl.crt同樣如果ssl.key已加密,需要輸入密碼。
自簽名,生成CA證書
CA證書是一種特殊的自簽名證書,可以用來(lái)對(duì)其它證書進(jìn)行簽名。這樣當(dāng)驗(yàn)證方選擇信任了CA證書,被簽名的其它證書就被信任了。在驗(yàn)證方進(jìn)行驗(yàn)證時(shí),CA證書來(lái)自操作系統(tǒng)的信任證書庫(kù),或者指定的證書列表。
生成自簽名證書的方法為:
openssl x509 -req -in sign.csr -extensions v3_ca -signkey sign.key -out sign.crt利用CA證書進(jìn)行簽名
使用CA證書對(duì)其它證書進(jìn)行簽名的方法為:
openssl x509 -req -in ssl.csr -extensions v3_usr -CA sign.crt -CAkey sign.key -CAcreateserial -out ssl.crt花錢購(gòu)買證書機(jī)構(gòu)的簽名
利用上述方法,受信任的機(jī)構(gòu)就可以用自己的私鑰(sign.key)對(duì)其他人的證書進(jìn)行簽名。我們看到,只需要把證書請(qǐng)求(ssl.csr)發(fā)給證書機(jī)構(gòu),證書機(jī)構(gòu)就可以生成出簽名過的證書(ssl.crt)。目前購(gòu)買證書簽名服務(wù)的價(jià)格大約為100-400元/年。
可選的證書機(jī)構(gòu)有:godaddy?startssl?namecheap
證書/私鑰格式
openssl默認(rèn)使用PEM格式(形如-----BEGIN CERTIFICATE----- ... ... -----END CERTIFICATE---)存放證書和私鑰,nginx/node.js可以使用該格式啟動(dòng)服務(wù)。
但使用tomcat或java客戶端/android時(shí),不能使用該格式的證書。jdk中包含了一個(gè)keytool命令,可以完成整個(gè)的證書生成過程,不過這里我們只用openssl工具也可以完成java的支持,即使用PKCS12格式對(duì)證書進(jìn)行打包。
PKCS12格式文件,可以包含多個(gè)證書/私鑰對(duì),指定多個(gè)受信任的server(也可以不包含證書),每個(gè)server有一個(gè)alias name。我們來(lái)看最簡(jiǎn)單的只包含一個(gè)alias的文件生成:
openssl pkcs12 -export -in sign.crt -inkey sign.key -out sign.p12上面的命令將CA證書及其私鑰導(dǎo)出為sign.p12文件,導(dǎo)出時(shí)需要指定一個(gè)密碼。
?
java客戶端程序中對(duì)p12文件進(jìn)行信任
如果我們的服務(wù)器使用了自己創(chuàng)建的CA證書簽名的證書,或者使用了自簽名證書,客戶端在使用ssl時(shí),需要將導(dǎo)出的證書文件加入到信任列表中。下面是一段導(dǎo)入證書的示例代碼:
1 javax.net.SocketFactory initSSLSocketFactory(InputStream keyin, char[] password) throws Exception { 2 java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS12"); 3 keyStore.load(keyin, password); 4 keyin.close(); 5 6 javax.net.ssl.TrustManagerFactory trustManagerFactory = javax.net.ssl.TrustManagerFactory.getInstance(javax.net.ssl.TrustManagerFactory.getDefaultAlgorithm()); 7 trustManagerFactory.init(keyStore); 8 9 javax.net.ssl.SSLContext sslContext = javax.net.ssl.SSLContext.getInstance("SSL"); 10 11 sslContext.init(null, trustManagerFactory.getTrustManagers(), null); 12 13 return sslContext.getSocketFactory(); 14 }我們得到了一個(gè)SocketFactory,可以用它來(lái)初始化ssl/https連接。
轉(zhuǎn)載于:https://www.cnblogs.com/zhengah/p/4998187.html
總結(jié)
以上是生活随笔為你收集整理的科普:TLS、SSL、HTTPS以及证书(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ovs笔记
- 下一篇: RPM包及其管理 rpm命令