HTTPs SSL CA

一張圖(燕姐課上講過,必考)對稱密鑰(DES/DES3/AES),非對稱密鑰(RSA公鑰加密,只有私鑰能解密。私鑰可以當作簽名使用,lhh,hsj不懂請自行百度一下)


簽名的流程示意圖:

1. CA建立,並頒發給自己根證書。
2. CA與瀏覽器開發者聯繫,將自己根證書綁定瀏覽器。
3. 網站服務器產生自己的公私鑰,並把自己信息和公鑰等信息作爲申請文件,請求 CA頒發 證書
4. CA覈實申請者信息,用私鑰(還是根證書呢?)給申請文件簽名,並頒發給網站服務器。
5. 網站服務器拿到簽名的證書,把它配置到 Apache等自己的服務器上。
6. 客戶端瀏覽網站時,網站服務器將證書發送給客戶端,客戶端驗證 CA的簽名。


以下是整個客戶—服務器驗證流程(耐心看):


假設A要想B發送消息,A會先計算出消息的消息摘要,然後使用自己的私鑰加密這段摘要加密,最後將加密後的消息摘要和消息一起發送給B,被加密的消息摘要就是“簽名”。

B收到消息後,也會使用和A相同的方法提取消息摘要,然後使用A的公鑰解密A發送的來簽名,並與自己計算出來的消息摘要進行比較。如果相同則說明消息是A發送給B的,同時,A也無法否認自己發送消息給B的事實。

數字簽名的作用是保證數據完整性,機密性和發送方角色的不可抵賴性。

如果甲想給乙發一個安全的保密的數據,那麼應該甲乙各自有一對公私鑰,甲先用乙的公鑰加密這段

數據,再用自己的私鑰加密這段加密後的數據,最後再發給乙。這樣確保了內容即不會被讀取,也不會被篡改。

 二、證書及CA介紹

公鑰、私鑰、證書

一個公鑰對應一個私鑰。

密鑰對中,讓大家都知道的是公鑰,不告訴大家,只有自己知道的,是私鑰。

爲什麼需要用證書來替代公鑰?

答:在上面的加密簽名等過程中,我們都忽略了一點,那就是如何確保我們獲取的公鑰是正確的。第三者很容易製作一個公鑰來冒充我們的交互目標,我們沒法憑藉這個公鑰來確認對方的身份。在這樣的情況下,證書就誕生了,證書是一個包裝了公鑰的實體,他裏面包含了公鑰,機構名稱,證書有效期,ca簽名等信息。這樣我們獲取證書後,就可以通過證書裏面對機構的描述來確認對方的身份。

證書中的ca是什麼意思?

答:其實上面對證書的描述並沒有完全解決我們提出的問題,第三者完全可能製作一個證書,而證書裏的機構信息也是僞造的。那麼ca就在這種情形下出現了。ca是證書頒發機構(certification authority)。ca是第三方的,爲數不多的,可信賴的機構,我們可以在其官網上獲取他的公鑰,用他的公鑰來解析ca簽名,就能夠唯一的驗證這個證書是由這個ca機構頒發的。ca機構會維護自己的publickey庫,比如公司“通聯支付”去ca申請證書後,那第三者就無法再以“通聯支付”的名字來申請證書了。那麼也就能驗證這個證書不是由第三者假冒的了。

Ca的分級認證模式

假設C證書信任A和B;然後A信任A1和A2;B信任B1和B2。則它們之間構成如下的一個樹形關係(一個倒立的樹)。

處於最頂上的樹根位置的那個證書,就是“根證書”。除了根證書,其它證書都要依靠上一級的證書,來證明自己。而根證書自己證明自己,或者換句話說,根證書是不需要被證明的。

瀏覽器如何識別證書的有效性?

瀏覽器默認會導入當地比較大的ca機構簽發的二級證書。當用戶訪問https網站時,瀏覽器通過ssl協議首先下載網站的證書,然後通過本地的ca二級證書對網站的證書進行驗籤。如果驗籤不通過,則一般都會出現警告彈窗。

證書和CA的出現,旨在解決公鑰的準確性,進而確保RSA算法進行加密和簽名的可靠性。

三、HTTPS詳細介紹(重要:老師課上講過的

https認證分爲單向認證和雙向認證,單向認證適用與互聯網大衆用戶;雙向認證適用與企業內部,集羣內部。

單向認證:客戶端無證書,客戶端認證服務端發送過來的證書,從而認證服務端。後續通過ssl握手,建立對稱加密通訊。

雙向認證:客戶端有證書,客戶端認證服務器發送過來的證書,服務端認證客戶端發送過來的證書,互相認證。後續通過ssl握手,建立對稱加密通訊。

交互流程(一個加密通信過程的演化)

我們來看一個例子,現在假設“服務器”和“客戶”要在網絡上通信,並且他們打算使用RSA來對通信進行加密以保證談話內容的安全。由於是使用RSA這種公鑰密碼體制,“服務器”需要對外發布公鑰(算法不需要公佈,RSA的算法大家都知道),自己留着私鑰。“客戶”通過某些途徑拿到了“服務器”發佈的公鑰,客戶並不知道私鑰。“客戶”具體是通過什麼途徑獲取公鑰的,我們後面再來說明,下面看一下雙方如何進行保密的通信:

2.1 第一回合:

“客戶”->“服務器”:你好

“服務器”->“客戶”:你好,我是服務器 “客戶”->“服務器”:我的賬號和密碼是...

因爲消息是在網絡上傳輸的,有人可以冒充自己是“服務器”來向客戶發送信息。例如上面的消息可以被黑客截獲如下:

“客戶”->“黑客”:你好 // 黑客在“客戶”和“服務器”之間的某個路由器上截獲“客戶”發給服務器的信息,然後自己冒充“服務器” “黑客”->“客戶”:你好,我是服務器

因此“客戶”在接到消息後,並不能肯定這個消息就是由“服務器”發出的,某些“黑客”也可以冒充“服務器”發出這個消息。如何確定信息是由“服務器”發過來的呢?有一個解決方法,因爲只有服務器有私鑰,所以如果只要能夠確認對方有私鑰,那麼對方就是“服務器”。因此通信過程可以改進爲如下:

2.2 第二回合:

“客戶”->“服務器”:你好

“服務器”->“客戶”:你好,我是服務器 “客戶”->“服務器”:向我證明你就是服務器

“服務器”->“客戶”:你好,我是服務器 {你好,我是服務器}[私鑰|RSA]

// 注意這裏約定一下,{} 表示RSA加密後的內容,[ | ]表示用什麼密鑰和算法進行加密,後面的示例中都用這種表示方式,例如上面的 {你好,我是服務器}[私鑰|RSA] 就表示用私鑰對“你好,我是服務器”進行加密後的結果。

爲了向“客戶”證明自己是“服務器”, “服務器”把一個字符串用自己的私鑰加密,把明文和加密後的密文一起發給“客戶”。對於這裏的例子來說,就是把字符串 “你好,我是服務器”和這個字符串用私鑰加密後的內容 {你好,我是服務器}[私鑰|RSA] 發給客戶。 “客戶”收到信息後,她用自己持有的公鑰解密密文,和明文進行對比,如果一致,說明信息的確是由服務器發過來的。也就是說“客戶”把 {你好,我是服務器}[私鑰|RSA] 這個內容用公鑰進行解密,然後和“你好,我是服務器”對比。因爲由“服務器”用私鑰加密後的內容,由並且只能由公鑰進行解密,私鑰只有“服務器”持有,所以如果解密出來的內容是能夠對得上的,那說明信息一定是從“服務器”發過來的。

假設“黑客”想冒充“服務器”:

“黑客”->“客戶”:你好,我是服務器 “客戶”->“黑客”:向我證明你就是服務器

“黑客”->“客戶”:你好,我是服務器 {你好,我是服務器}[???|RSA] //這裏黑客無法冒充,因爲他不知道私鑰,無法用私鑰加密某個字符串後發送給客戶去驗證。 “客戶”->“黑客”:我的賬號和密碼是...

由於“黑客”沒有“服務器”的私鑰,因此它發送過去的內容,“客戶”是無法通過服務器的公鑰解密的,因此可以認定對方是個冒牌貨!

到這裏爲止,“客戶”就可以確認“服務器”的身份了,可以放心和“服務器”進行通信,但是這裏有一個問題,通信的內容在網絡上還是無法保密。爲什麼無法保密呢?通信過程不是可以用公鑰、私鑰加密嗎?其實用RSA的私鑰和公鑰是不行的,我們來具體分析下過程,看下面的演示:

2.3 第三回合:

“客戶”->“服務器”:你好

“服務器”->“客戶”:你好,我是服務器 “客戶”->“服務器”:向我證明你就是服務器

“服務器”->“客戶”:你好,我是服務器 {你好,我是服務器}[私鑰|RSA]

“客戶”->“服務器”:{我的帳號是aaa,密碼是123,把我的餘額的信息發給我看看}[公鑰|RSA]

“服務器”->“客戶”:{你的餘額是100元}[私鑰|RSA]

注意上面的的信息 {你的餘額是100元}[私鑰],這個是“服務器”用私鑰加密後的內容,但是我們之前說了,公鑰是發佈出去的,因此所有的人都知道公鑰,所以除了“客戶”,其它的人也可以用公鑰對{你的餘額是100元}[私鑰]進行解密。所以如果“服務器”用私鑰加密發給“客戶”,這個信息是無法保密的,因爲只要有公鑰就可以解密這內容。然而“服務器”也不能用公鑰對發送的內容進行加密,因爲“客戶”沒有私鑰,發送給“客戶”也解密不了。 這樣問題就又來了,那又如何解決呢?在實際的應用過程,一般是通過引入對稱加密來解決這個問題,看下面的演示:


2.4 第四回合:

“客戶”->“服務器”:你好

“服務器”->“客戶”:你好,我是服務器 “客戶”->“服務器”:向我證明你就是服務器

“服務器”->“客戶”:你好,我是服務器 {你好,我是服務器}[私鑰|RSA]

“客戶”->“服務器”:{我們後面的通信過程,用對稱加密來進行,這裏是對稱加密算法和密鑰}[公鑰|RSA] //藍色字體的部分是對稱加密的算法和密鑰的具體內容,客戶把它們發送給服務器。

“服務器”->“客戶”:{OK,收到!}[密鑰|對稱加密算法]

“客戶”->“服務器”:{我的帳號是aaa,密碼是123,把我的餘額的信息發給我看看}[密鑰|對稱加密算法]

“服務器”->“客戶”:{你的餘額是100元}[密鑰|對稱加密算法]

在上面的通信過程中,“客戶”在確認了“服務器”的身份後,“客戶”自己選擇一個對稱加密算法和一個密鑰,把這個對稱加密算法和密鑰一起用公鑰加密後發送給“服務器”。注意,由於對稱加密算法和密鑰是用公鑰加密的,就算這個加密後的內容被“黑客”截獲了,由於沒有私鑰,“黑客”也無從知道對稱加密算法和密鑰的內容。 由於是用公鑰加密的,只有私鑰能夠解密,這樣就可以保證只有服務器可以知道對稱加密算法和密鑰,而其它人不可能知道(這個對稱加密算法和密鑰是“客戶”自己選擇的,所以“客戶”自己當然知道如何解密加密)。這樣“服務器”和“客戶”就可以用對稱加密算法和密鑰來加密通信的內容了。

但是這裏還留有一個問題,在最開始我們就說過,“服務器”要對外發布公鑰,那“服務器”如何把公鑰發送給“客戶”呢?我們第一反應可能會想到以下的兩個方法: a)把公鑰放到互聯網的某個地方的一個下載地址,事先給“客戶”去下載。 b)每次和“客戶”開始通信時,“服務器”把公鑰發給“客戶”。 但是這個兩個方法都有一定的問題,

對於a)方法,“客戶”無法確定這個下載地址是不是“服務器”發佈的,你憑什麼就相信這個地址下載的東西就是“服務器”發佈的而不是別人僞造的呢,萬一下載到一個假的怎麼辦?另外要所有的“客戶”都在通信前事先去下載公鑰也很不現實。

對於b)方法,也有問題,因爲任何人都可以自己生成一對公鑰和私鑰,他只要向“客戶”發送他自己的私鑰就可以冒充“服務器”了。示意如下:

“客戶”->“黑客”:你好 //黑客截獲“客戶”發給“服務器”的消息

“黑客”->“客戶”:你好,我是服務器,這個是我的公鑰 //黑客自己生成一對公鑰和私鑰,把公鑰發給“客戶”,自己保留私鑰 “客戶”->“黑客”:向我證明你就是服務器

“黑客”->“客戶”:你好,我是服務器 {你好,我是服務器}[黑客自己的私鑰|RSA] //客戶收到“黑客”用私鑰加密的信息後,是可以用“黑客”發給自己的公鑰解密的,從而會誤認爲“黑客”是“服務器”

因此“黑客”只需要自己生成一對公鑰和私鑰,然後把公鑰發送給“客戶”,自己保留私鑰,這樣由於“客戶”可以用黑客的公鑰解密黑客的私鑰加密的內容,“客戶”就會相信“黑客”是“服務器”,從而導致了安全問題。這裏問題的根源就在於,大家都可以生成公鑰、私鑰對,無法確認公鑰對到底是誰的。 如果能夠確定公鑰到底是誰的,就不會有這個問題了。例如,如果收到“黑客”冒充“服務器”發過來的公鑰,經過某種檢查,如果能夠發現這個

公鑰不是“服務器”的就好了。

爲了解決這個問題,數字證書出現了,它可以解決我們上面的問題。

這裏先只需要搞清楚一點,數字證書可以保證數字證書裏的公鑰確實是這個證書的所有者(Subject)的,或者證書可以用來確認對方的身份。也就是說,我們拿到一個數字證書,我們可以判斷出這個數字證書到底是誰的。至於是如何判斷的,後面會在詳細討論數字證書時詳細解釋。現在把前面的通信過程使用數字證書修改爲如下:

2.5 第五回合:

“客戶”->“服務器”:你好

“服務器”->“客戶”:你好,我是服務器,這裏是我的數字證書 //這裏用證書代替了公鑰

“客戶”->“服務器”:向我證明你就是服務器

“服務器”->“客戶”:你好,我是服務器 {你好,我是服務器}[私鑰|RSA]

注意,上面第二次通信,“服務器”把自己的證書發給了“客戶”,而不是發送公鑰。“客戶”可以根據證書校驗這個證書到底是不是“服務器”的,也就是能校驗這個證書的所有者是不是“服務器”,從而確認這個證書中的公鑰的確是“服務器”的。後面的過程和以前是一樣,“客戶”讓“服務器”證明自己的身份,“服務器”用私鑰加密一段內容連同明文一起發給“客戶”,“客戶”把加密內容用數字證書中的公鑰解密後和明文對比,如果一致,那麼對方就確實是“服務器”,然後雙方協商一個對稱加密來保證通信過程的安全。到這裏,整個過程就完整了,我們回顧一下:

2.6 完整過程:

step1: “客戶”向服務端發送一個通信請求 “客戶”->“服務器”:你好

step2: “服務器”向客戶發送自己的數字證書。證書中有一個公鑰用來加密信息,私鑰由“服務器”持有

“服務器”->“客戶”:你好,我是服務器,這裏是我的數字證書

step3: “客戶”收到“服務器”的證書後,它會去驗證這個數字證書到底是不是“服務器”的,數字證書有沒有什麼問題,數字證書如果檢查沒有問題,就說明數字證書中的公鑰確實是“服務器”的。檢查數字證書後,“客戶”會發送一個隨機的字符串給“服務器”用私鑰去加密,服務器把加密的結果返回給“客戶”,“客戶”用公鑰解密這個返回結果,如果解密結果與之前生成的隨機字符串一致,那說明對方確實是私鑰的持有者,或者說對方確實是“服務器”。

“客戶”->“服務器”:向我證明你就是服務器,這是一個隨機字符串 //前面的例子中爲了方便解釋,用的是“你好”等內容,實際情況下一般是隨機生成的一個字符串。 “服務器”->“客戶”:{一個隨機字符串}[私鑰|RSA]

step4: 驗證“服務器”的身份後,“客戶”生成一個對稱加密算法和密鑰,用於後面的通信的加密和解密。這個對稱加密算法和密鑰,“客戶”會用公鑰加密後發送給“服務器”,別人截獲了也沒用,因爲只有“服務器”手中有可以解密的私鑰。這樣,後面“服務器”和“客戶”就都可以用對稱加密算法來加密和解密通信內容了。

“服務器”->“客戶”:{OK,已經收到你發來的對稱加密算法和密鑰!有什麼可以幫到你的?}[密鑰|對稱加密算法]

“客戶”->“服務器”:{我的帳號是aaa,密碼是123,把我的餘額的信息發給我看看}[密鑰|對稱加密算法]

“服務器”->“客戶”:{你好,你的餘額是100元}[密鑰|對稱加密算法] ?? //繼續其它的通信

以上就是課程內容!


實驗(相關文件已傳至微信羣):


實驗1.1(網站的搭建)

環境:ubuntu 14;mysql;php5.5;apache2

1.環境安裝

sudo apt-get install apache2
sudo apt-get install mysql-server mysql-common mysql-client//密碼記好之後要用,用戶名默認root
sudo apt-get install php5-common php5-gd libapache2-mod-auth-mysql php5-mysql apache2-mpm-prefork libapache2-mod-php5 php5 php5-cli

2.建數據庫

進數據庫:mysql -uroot -p

create database myzoo;
use myzoo; 
create table Person(PersonID int primary key auto_increment, Password varchar(100),Salt varchar(100),Username varchar(100),Token varchar(100),Zoobars int default 10, Profile varchar(5000));
退出數據庫:quit


3.把燕姐提供的myzoo文件夾拷貝到var/www(不需要新建,系統裏有的)目錄下


4.進到myzoo文件夾(myzoo如果進不去就需要修改權限chmod -R 777 myzoo/)


5.修改database.class.php

cd includes/
sudo vim database.class.php
修改用戶名爲“root” ,密碼爲自己設定的,數據庫名爲“myzoo”


6.修改000-default.conf(文件目錄:etc/apache2/sites-available/000-default.conf)

sudo vim 000-default.conf
將DocumentRoot /var/www/html中的html替換爲myzoo


7.重啓apache2

sudo service apache2 restart
8.打開瀏覽器

輸入:localhost(動物園就出現了)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章