亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

前段時(shí)間在做HTTPS相關(guān)的需求碰到了一些問題,今天有空整理一下HTTPS的相關(guān)知識(shí),希望對您能有所幫助。

圖片圖片

什么是HTTPS

HTTPS,即HTTP Security,是建立在SSL / TSL協(xié)議之上,其中,TSL是SSL協(xié)議的升級(jí)版,TLS 1.0通常被標(biāo)示為SSL 3.1,TLS 1.1為SSL 3.2,TLS 1.2為SSL 3.3,可以理解為同一套協(xié)議。他的作用主要以下三點(diǎn):

防止竊聽。 所有信息都是加密傳播,第三方無法竊聽。

防止篡改。具有校驗(yàn)機(jī)制,一旦被篡改,通信雙方會(huì)立刻發(fā)現(xiàn)。

防止冒充。配備身份證書,防止身份被冒充。本文將從Android使用者的角度,盡量解釋清楚什么是HTTPS。

TLS驗(yàn)證流程

TLS驗(yàn)證流程

交互流程如下:

  1. 客戶端發(fā)出請求給服務(wù)端,請求的內(nèi)容包括:
  1. 支持的協(xié)議版本,比如TLS 1.0版。
  2. 一個(gè)客戶端生成的隨機(jī)數(shù),稍后用于生成"對話密鑰"。
  3. 支持的加密方法,比如RSA公鑰加密。
  4. 支持的壓縮方法。
  1. 服務(wù)器回應(yīng)客戶端,包含以下內(nèi)容:
  2. 確認(rèn)使用的加密通信協(xié)議版本,比如TLS 1.0版本。如果瀏覽器與服務(wù)器支持的版本不一致,服務(wù)器關(guān)閉加密通信。
  3. 一個(gè)服務(wù)器生成的隨機(jī)數(shù),稍后用于生成"對話密鑰"。
  4. 確認(rèn)使用的加密方法,比如RSA公鑰加密。
  5. 服務(wù)器證書。
  6. 客戶端收到服務(wù)器回應(yīng)以后,首先驗(yàn)證服務(wù)器證書。如果證書不是可信機(jī)構(gòu)頒布、或者證書中的域名與實(shí)際域名不一致、或者證書已經(jīng)過期,就會(huì)向訪問者顯示一個(gè)警告,由其選擇是否還要繼續(xù)通信。
    如果證書沒有問題,客戶端就會(huì)從證書中取出服務(wù)器的公鑰。然后,向服務(wù)器發(fā)送下面三項(xiàng)信息。
  7. 一個(gè)隨機(jī)數(shù)。該隨機(jī)數(shù)用服務(wù)器公鑰加密,防止被竊聽。
  8. 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送。
  9. 客戶端握手結(jié)束通知,表示客戶端的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)也是前面發(fā)送的所有內(nèi)容的hash值,用來供服務(wù)器校驗(yàn)。
  10. 服務(wù)器收到客戶端的第三個(gè)隨機(jī)數(shù)pre-master key之后,計(jì)算生成本次會(huì)話所用的"會(huì)話密鑰"。然后,向客戶端最后發(fā)送下面信息。
  11. 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送。
  12. 服務(wù)器握手結(jié)束通知,表示服務(wù)器的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)也是前面發(fā)送的所有內(nèi)容的hash值,用來供客戶端校驗(yàn)。

至于為什么一定要用三個(gè)隨機(jī)數(shù),來生成"會(huì)話密鑰",dog250解釋得很好:

"不管是客戶端還是服務(wù)器,都需要隨機(jī)數(shù),這樣生成的密鑰才不會(huì)每次都一樣。由于SSL協(xié)議中證書是靜態(tài)的,因此十分有必要引入一種隨機(jī)因素來保證協(xié)商出來的密鑰的隨機(jī)性。

對于RSA密鑰交換算法來說,pre-master-key本身就是一個(gè)隨機(jī)數(shù),再加上hello消息中的隨機(jī),三個(gè)隨機(jī)數(shù)通過一個(gè)密鑰導(dǎo)出器最終導(dǎo)出一個(gè)對稱密鑰。

pre master的存在在于SSL協(xié)議不信任每個(gè)主機(jī)都能產(chǎn)生完全隨機(jī)的隨機(jī)數(shù),如果隨機(jī)數(shù)不隨機(jī),那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機(jī)因素,那么客戶端和服務(wù)器加上pre master secret三個(gè)隨機(jī)數(shù)一同生成的密鑰就不容易被猜出了,一個(gè)偽隨機(jī)可能完全不隨機(jī),可是是三個(gè)偽隨機(jī)就十分接近隨機(jī)了,每增加一個(gè)自由度,隨機(jī)性增加的可不是一。"

HTTPS相關(guān)名詞

HTTPS涉及到的概念比較多,什么X509,.pem,.crt等等,理解了HTTPS的交互流程之后,先來理一理這些概念。

  • X509 - 這是一種證書標(biāo)準(zhǔn),主要定義了證書中應(yīng)該包含哪些內(nèi)容.其詳情可以參考RFC5280,SSL使用的就是這種證書標(biāo)準(zhǔn)。
  • PEM - Privacy Enhanced MAIl,打開看文本格式,以"-----BEGIN..."開頭, "-----END..."結(jié)尾,內(nèi)容是BASE64編碼.查看PEM格式證書的信息:
openssl x509 -in certificate.pem -text -noout

Apache和*NIX服務(wù)器偏向于使用這種編碼格式.

  • DER - Distinguished Encoding Rules,打開看是二進(jìn)制格式,不可讀.查看DER格式證書的信息:
openssl x509 -in certificate.der -inform der -text -noout

JAVA和windows服務(wù)器偏向于使用這種編碼格式.

上面是證書標(biāo)準(zhǔn)和兩種常用的編碼格式。下面我們來認(rèn)識(shí)一下都有哪些文件擴(kuò)展名。

  • CRT - CRT應(yīng)該是certificate的三個(gè)字母,其實(shí)還是證書的意思,常見于*NIX系統(tǒng),有可能是PEM編碼,也有可能是DER編碼,大多數(shù)應(yīng)該是PEM編碼,相信你已經(jīng)知道怎么辨別.
  • CER - 還是certificate,還是證書,常見于Windows系統(tǒng),同樣的,可能是PEM編碼,也可能是DER編碼,大多數(shù)應(yīng)該是DER編碼.
  • KEY - 通常用來存放一個(gè)公鑰或者私鑰,并非X.509證書,編碼同樣的,可能是PEM,也可能是DER.查看KEY的辦法:
openssl rsa -in mykey.key -text -noout

如果是DER格式的話,同理應(yīng)該這樣了:openssl rsa -in mykey.key -text -noout -inform der

  • CSR - Certificate Signing Request,即證書簽名請求,這個(gè)并不是證書,而是向權(quán)威證書頒發(fā)機(jī)構(gòu)獲得簽名證書的申請,其核心內(nèi)容是一個(gè)公鑰(當(dāng)然還附帶了一些別的信息),在生成這個(gè)申請的時(shí)候,同時(shí)也會(huì)生成一個(gè)私鑰,私鑰要自己保管好.做過IOS App的朋友都應(yīng)該知道是怎么向蘋果申請開發(fā)者證書的吧.查看的辦法:(如果是DER格式的話照舊加上-inform der,這里不寫了)
openssl req -noout -text -in my.csr
  • PFX/P12 - predecessor of PKCS#12,對*nix服務(wù)器來說,一般CRT和KEY是分開存放在不同文件中的,但Windows的IIS則將它們存在一個(gè)PFX文件中,(因此這個(gè)文件包含了證書及私鑰)這樣會(huì)不會(huì)不安全?應(yīng)該不會(huì),PFX通常會(huì)有一個(gè)"提取密碼",你想把里面的東西讀取出來的話,它就要求你提供提取密碼,PFX使用的時(shí)DER編碼,如何把PFX轉(zhuǎn)換為PEM編碼?
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes

這個(gè)時(shí)候會(huì)提示你輸入提取代碼. for-iis.pem就是可讀的文本.生成pfx的命令類似這樣:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt

其中CACert.crt是CA(權(quán)威證書頒發(fā)機(jī)構(gòu))的根證書,有的話也通過-certfile參數(shù)一起帶進(jìn)去.這么看來,PFX其實(shí)是個(gè)證書密鑰庫.

  • JKS - 即Java Key Storage,這是Java的專利,跟OpenSSL關(guān)系不大,利用Java的一個(gè)叫"keytool"的工具,可以將PFX轉(zhuǎn)為JKS,當(dāng)然了,keytool也能直接生成JKS,不過在此就不多表了.
  • BKS - 來自BouncyCastleProvider,它使用的也是TripleDES來保護(hù)密鑰庫中的Key,它能夠防止證書庫被不小心修改(Keystore的keyentry改掉1個(gè)bit都會(huì)產(chǎn)生錯(cuò)誤),BKS能夠跟JKS互操作。通過以下命令可以將crt轉(zhuǎn)換成bks,也就是說,其實(shí)bks就是上文說的證書文件,jks也是。
keytool -importcert -tRustcacerts -keystore e:key.bks -file e:server.crt -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider

bks的生成參考:SSL通信中使用的bks格式證書的生成

Java上的HTTPS

java上使用HTTPS很簡單,一個(gè)典型的HTTPS方式如下:

URL url = new URL("https://google.com");  
HttpsURLConnection urlConnection = url.openConnection();  
InputStream in = urlConnection.getInputStream();

此時(shí)使用的是默認(rèn)的SSLSocketFactory,與下段代碼使用的SSLContext是一致的

private synchronized SSLSocketFactory getDefaultSSLSocketFactory() {  
  try {
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, null, null);
    return defaultSslSocketFactory = sslContext.getSocketFactory();
  } catch (GeneralSecurityException e) {
    throw new AssertionError(); // The system has no TLS. Just give up.
  }
}

這段代碼里面最重要的方法是sslContext.init(null, null, null);,這里有三個(gè)參數(shù),分別是:

  • KeyManager[],自己的證書,用來校驗(yàn)服務(wù)端是否可信,如果是單向校驗(yàn)則傳空,表示不需要校驗(yàn)服務(wù)端。
  • TrustManager[],認(rèn)證服務(wù)端證書是否可信,如果傳空則使用android自己的證書庫,如果服務(wù)端證書的辦法機(jī)構(gòu)在默認(rèn)庫里面,則校驗(yàn)通過。

有時(shí)候CA也是不可信的,為了獲得更高的安全新,需要我們自己指定新人的錨點(diǎn),可以采用如下的代碼:

// 取到證書的輸入流
InputStream is = new FileInputStream("anchor.crt");  
CertificateFactory cf = CertificateFactory.getInstance("X.509");  
Certificate ca = cf.generateCertificate(is);


// 創(chuàng)建 Keystore 包含我們的證書
String keyStoreType = KeyStore.getDefaultType();  
KeyStore keyStore = KeyStore.getInstance(keyStoreType);  
keyStore.load(null);  
keyStore.setCertificateEntry("anchor", ca);


// 創(chuàng)建一個(gè) TrustManager 僅把 Keystore 中的證書 作為信任的錨點(diǎn)
String algorithm = TrustManagerFactory.getDefaultAlgorithm();  
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(algorithm);  
trustManagerFactory.init(keyStore);  
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();


// 用 TrustManager 初始化一個(gè) SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");  
sslContext.init(null, trustManagers, null);  
return sslContext.getSocketFactory();

這種情況下,只有 anchor.crt 以及他簽發(fā)的證書才會(huì)被信任。

  • SecureRandom,也就是生成隨機(jī)數(shù)的策略,一般都是直接new SecureRandom()作為參數(shù)傳進(jìn)去。

注意這里使用的是單向認(rèn)證,也就是只需要客戶端驗(yàn)證服務(wù)端的證書,客戶端本地部緩存證書,所以這里sslContext.init()方法的三個(gè)參數(shù)都是空的。

默認(rèn)的 SSLSocketFactory 校驗(yàn)服務(wù)器的證書時(shí)(也就是TrustManager[]傳空的時(shí)候),會(huì)信任設(shè)備內(nèi)置的100多個(gè)根證書。

既然有單向驗(yàn)證,那么也有雙向驗(yàn)證,即不僅僅客戶端需要校驗(yàn)服務(wù)端,服務(wù)端也需要驗(yàn)證客戶端。這種情況下,客戶端需要將自己的證書發(fā)給服務(wù)端做驗(yàn)證,這種情況只需要將證書的KeyManager作為在init()的第一個(gè)參數(shù)來SSLContext就行了。

分享到:
標(biāo)簽:HTTPS
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評(píng)定2018-06-03

通用課目體育訓(xùn)練成績評(píng)定