1. 程式人生 > >ssl協議、openssl以及建立私有CA

ssl協議、openssl以及建立私有CA

實驗環境:RHEL5.8 32Bit

SSL協議、OpenSSL以及建立私有CA詳解

·如果通訊雙方其中某一方的私鑰丟失了該怎麼辦?

    在通訊的過程中,收發雙反任何一方的私鑰丟失,都會導致它們的數字證書失效,所以任何基於此證書建立的通訊都應該宣佈失效,那麼我們應該如何在網際網路上實現這種失效的功能呢?這種功能其實還是得依靠CA來實現,事實上一個完整的CA,還應該維護一個列表,叫做CRL(證書吊銷列表)。

·CRL

    CRL中儲存的是此前CA所發出的所有證書,這些證書還沒有過期,只不過由於各種原因證書已經被吊銷了,證書也是有有效期的,所以說有了CRL之後,收發雙方進行通訊的機制是這樣的:

    首先,接收方為了能夠和傳送方進行通訊,會去申請獲得傳送方的證書,接著傳送方就會將自己的證書傳送給接收方,接收方在得到證書之後,先去驗證該證書的有效性,即該證書上的數字簽名是不是自己所信任的證書頒發機構所頒發的,也就是驗證是否能夠使用發證機構的公鑰對該證書的數字簽名進行解密,如果可以解密並且解密完成之後,接著就會去驗證該證書資訊的資料的完整性,通過資料的特徵碼來驗證,驗證完了數字證書資料資訊的資料完整性之後,如果完整的話就可以獲得傳送方的公鑰資訊了,事實上真正可靠的做法是,接收方在獲得傳送方的數字證書之後,先去驗證該證書是否是自己所信任的證書頒發機構所頒發的,接著再去檢視該證書是否在CRL這個列表裡面,如果該證書在CRL裡面,那麼也應該拒絕使用該證書,但是在網際網路的通訊中,大部分使用者都會忽略這一點,所以有證書的通訊也不一定是安全的,故CRL是保證證書安全性的一個非常重要的措施,並且我們在每一次使用證書之前都應該去驗證它的有效性,數字證書的驗證流程:

wKiom1hwo_nxgsXWAABDLyFTvEI413.png    

    因此一個證書頒發機構,包括其CRL,以及CA間的信任關係的組合構成了整個PKI系統的核心。

·CA(Certificate Authority)

    證書頒發機構,PKI的核心就是CA。

·一個數字證書當中都應該包含什麼樣的資訊呢?

    不同標準下的數字證書的格式是不同的,目前比較流行的證書的格式是x509格式,這種格式是標準格式最通行的格式,x509格式的證書中主要包含了以下幾個方面的資訊:

    1,公鑰及其使用期限

    2,證書的合法擁有者

    3,證書該如何被使用

    證書的用途是有限定的,不能隨便的去使用。

    4,CA的資訊

    5,CA簽名的校驗碼(CA的公鑰,CA頒發的數字證書的簽名是被CA的私鑰所加密的)

·TLS/SSL

    這是網際網路上著名的安全機制,它們使用的證書的格式正是x509的格式,TLS/SSL就是一種PKI的實現,還有一種PKI的實現叫做OpenGPG,這兩種PKI實現的證書管理機制是不同的或者這兩種PKI實現的CA間信任關係的傳遞機制略有不同,而在我們的Linux作業系統上,OpenGPG也是一種PKI的實現架構,意思就是如果我們想要在網際網路的通訊過程當中實現資料的加密,數字證書的簽名、身份的驗證等各種功能得依賴於PKI,而PKI的實現卻有兩種形式,一種是基於TLS/SSL的PKI實現,另一種是基於OpenGPG的PKI的實現,OpenGPG的證書格式和x509的證書格式是差不多的,那麼TLS/SSL到底是什麼?它是如何實現握手認證(Handshake)以及金鑰交換等各種功能的:

TCP/IP四層模型中的應用層是否能夠加密傳輸資料依賴的是具體的傳輸協議,http、smtp以及ftp協議在進行資料傳輸的時候都是明文傳輸的,但是https協議使得我們在訪問網際網路web伺服器的時候資料可以進行加密傳輸,https使用的443埠,而http使用的是80埠,二者是完全不同的兩個協議。

·https

    https協議是由美國網景(Netscape)公司所開發的,網景公司是全球第一款最流行的瀏覽器生產商,就是我們所熟知的Navigator瀏覽器,網景公司同時也提供了網際網路上第一款web伺服器軟體,但是後來網景公司被Sun公司收購了,因為當時網景公司已經被微軟公司徹底打敗了,http協議在傳輸資料的過程中是明文傳輸的,但是為了實現基於http的加密傳輸資料的協議,網景公司在應用層和TCP層之間又加入了半個層,這半個層就叫做SSL層:

    wKiom1haQnnTcswiAAAcaVlsBVw762.png              wKiom1haREvBkt9gAAAZ3_ZXy60802.png

·SSL(Secure Socket Layer)

    安全的套接字層,SSL發展到今天已經有很多的版本了,比如SSLv1、SSLv2以及SSLv3,目前比較流行的版本是v2和v3版,v1版已經不再使用了,SSL只是一個庫,因此如果我們想要實現SSL的功能,只需要在我們的系統上提供SSL相關的庫檔案即可,就能夠將http封裝成為https,那就意味著我們能夠支援https協議了,但是http協議本身是不會經由SSL層封裝的,因此http和https是兩個完全不同的協議,但是二者在應用層所實現的功能是一樣的,只不過底層的協議棧是不同的,因為https協議的封裝層次多了一個SSL層的封裝,由此導致二者底層的所有封裝都會趨於不同,SSL不是一個軟體,它只是一個庫,在應用層封裝好的傳輸協議,如果在傳輸資料到傳輸層之前呼叫了SSL層的功能的話,那麼這個協議在傳輸資料的過程中就能夠實現加密傳輸的功能了,例如http協議原本在傳輸資料的過程中是無法實現加密傳輸的,它在應用層封裝完畢之後就會將資料交給傳輸層,但是由於Netscape在傳輸層之前又新增了一個SSL層,因此http資料包在傳輸給傳輸層之前會在SSL層再做一次封裝,而SSL層本身就是實現資料安全通訊的,因此http搖身一變就變成了https協議,同理smtp協議就變成了smtps協議,ftp協議就變成了ftps協議,眾多應用層的明文協議都可以通過呼叫SSL層的功能實現資料的安全傳輸,SSL是由網景公司研發的協議,之後國際標準化組織決定研發一個在全球範圍內更加流行且更為開放的另一個層次上的通用性協議,就是TLS協議。

·TLS(Transport Layer Security)

    傳輸層安全,TLS目前的版本就是它的第一版,叫做TLSv1,事實上TLSv1就相當於是SSLv3,二者所實現的功能的原理和機制是差不多的,以後我們可以不加區別的來說TLS和SSL,因為在有些系統中二者的實現機制是一樣的,雖然協議有可能不同。

·在兩臺主機之間的SSL會話是如何實現的?

    以http協議為例,http協議是基於TCP協議的,因此收發雙方在進行http會話之前首先會進行三次握手,但是如果是https協議的話,也會先進行三次握手來保證通訊連線的建立,接下來:

    第一步,客戶端會向服務端發起會話請求,此時,服務端不會直接向客戶端傳遞http協議包,而是先去和客戶端協商建立SSL會話,這個協商的過程不僅要協商使用SSL協議還是TLS協議,還得要協商使用何種對稱加密演算法,應該選擇一個雙方共同支援的,而且比較理想的對稱加密演算法。

    第二步,服務端會將自己的證書傳送給客戶端,一般而言客戶端都沒有證書,客戶端在收到證書之後,首先會去驗證證書是否為自己所信任的CA所頒發的,之後會去驗證證書的完整性,如果證書驗證通過,客戶端就會通過證書得到服務端的公鑰。

    第三步,客戶端會去建立一個會話金鑰,https協議的主要作用在於使得web伺服器的資料交換是通過加密的方式進行的,加密使用對稱加密的演算法,因為非對稱加密演算法的加密速度太慢,這個對稱密碼是客戶端通過自己主機內部的隨機數選擇生成的一個隨機金鑰,並將這個隨機金鑰通過服務端的公鑰加密並且傳送給服務端。

    第四步,客戶端將加密的金鑰傳送給服務端,接下來服務端使用該隨機金鑰加密資料,並將加密後的資料傳送給客戶端。

wKioL1hwqimjq4WoAABbkXz2d-Y640.png

    以上就是SSL會話建立的全過程。

    SSL會話建立過程中的對稱金鑰是由客戶端自己選擇生成的,而不是基於Deffie-Hellman演算法實現的,我們通過之前的學習知道公鑰加密演算法可以實現身份驗證和資料的機密性兩種功能,但是這裡我們發現,公鑰加密演算法還可以實現金鑰交換的功能。

·常見加密演算法的總結

    一,對稱加密演算法

    對稱加密演算法的特性是加密和解密使用同一個金鑰,常見的對稱加密演算法主要有以下幾種:

      1,DES(Data Encryption Standard)資料加密標準

      這是一個比較早的而且比較成熟的加密演算法,是由美國國家安全域性在徵集加密演算法的時候,由IBM公司所提供的一種加密演算法,叫做資料加密標準,那時的計算機的執行速度非常的慢,DES使用的金鑰長度為56位,到2000年左右,人們已經可以輕而易舉的使用當時效能較強的計算機去破解DES加密演算法,至此DES加密演算法已經很少使用了,因為它不安全,後來人們發明了另外一種加密演算法,這個演算法的機制是將資料使用DES演算法加密3次,即3重DES,叫做3DES。

      2,3DES

      目前使用比較多的對稱加密演算法,叫做TripleDES。

      3,AES(Advanced Encryption Standard)高階加密標準

      是由美國國家安全域性徵集的更高級別的對稱加密演算法,叫做高階加密標準,AES使用128位的金鑰長度,安全性比較高,但是AES演算法有幾個變種,AES192、AES256以及AES512後面的數字表示使用的金鑰長度,越長安全性越高,但是金鑰越長加密的速度就會越慢,所以合適的加密演算法才是最好的。

      4,Blowfish

      這是一種常見的對稱加密演算法。

      我們資料本身其實都是一個一個的二進位制位,但是我們在給資料加密的時候不是一個位一個位加密的,這是不可能的,一般在給資料加密之前,我們會將整個資料分成大小相同的資料塊進行加密。

    二,單向加密演算法

        1,MD4

        2,MD5

        使用128位的定長輸出。

        3,SHA1

        使用160位的定長輸出,SHA1還有幾種變種,SHA192、SHA256以及SHA384後面的數字不是金鑰長度,而是輸出長度。

        4,CRC-32

        叫做迴圈冗餘校驗碼,不是一種加密演算法,而是一種校驗碼的計算機制,使用非常廣泛,但是不提供任何安全性,一般的單向加密演算法決不允許輸入不一樣而輸出卻一樣的情況發生,但是CRC-32演算法卻有可能出現這種情況,因為CRC-32不是為了加密,而是為了提供校驗功能。

    三,非對稱加密演算法

        也叫做公鑰加密演算法,實現的功能主要有兩個:加密和簽名,此種演算法的金鑰是成對出現的,金鑰的長度也是可以變化的,但是同理金鑰長度越長,加密速度越慢,而且公鑰加密主要實現的功能有三個,身份驗證(私鑰加密)、資料加密(公鑰加密)以及金鑰交換(公鑰加密),公鑰加密演算法中比較著名的演算法有兩種:

        1,RSA

         RSA既是一種演算法,又是一個公司的名稱,而且也是三位創始人的名稱,RSA既能實現加密又可以實現簽名。

        2,DSA

          DSA只能實現簽名,屬於美國國家安全域性,是公開使用的。

        還有一種商業演算法叫做ElGamal。

    眾所周知,加密和解密都得通過演算法來實現,那因此我們就需要一種工具,能夠在我們的主機上給我們提供這種演算法的實現,就是具體的能夠完成這種演算法的一個程式,我們稱之為具體的實現,而在Linux上,不同的加密演算法,或者不同的加密機制所能夠提供的工具是不同的,能夠實現加密演算法的工具主要有兩種:

    1,OpenSSL

2,gpg

·OpenSSL

    OpenSSL是SSL的開源實現,功能非常強大,幾乎實現了目前市面上所有的主流加密演算法,而且工作效能也非常的好,作者是兩個年輕人,OpenSSL是一個軟體,它是由三部分組成的:

    1,libcrpto

      通用加密庫,任何軟體想要實現加密功能,只要連結到這個庫上面即可,這個庫提供了各種加密函式。

    2,libssl

      TSL/SSL的實現/庫,正是有了它,我們的Linux才能夠使用https等協議,這是一個基於連線的,能夠實現認證、資料安全傳輸以及會話完整性的工具,所以SSL本身其實就是一個基於會話來實現的庫。

    3,openssl

      這是一個命令列工具,叫做多功能命令列工具,能夠實現單向加密、對稱加密以及非對稱加密,還能夠使用它來生成一對金鑰,而且還可以用它來模擬實現私有CA,是Linux上最基本的通用工具之一,該命令列工具的命令是由許多子命令組成的,和我們的yum命令相類似,不同的子命令用於實現不同的功能。

    wKiom1haeg_g06YEAADmqxp7oYk493.png      

    我們使用rpm -q 關鍵詞 命令可以檢視我們的系統上有沒有安裝和關鍵詞相關的軟體:

    wKioL1hae-2QpGK_AAAISdXj6mI323.png  

    rpm -ql 關鍵詞 命令可以檢視安裝的軟體生成的檔案:

         wKiom1hafFSx4vW8AAATfzc8jl8616.png

    OpenSSL在紅帽上的配置檔案叫做/etc/pki/tls/openssl.cnf,這個配置檔案在讓openssl工作成為私有CA時會用到,平時我們在使用openssl命令列的時候是用不到這個檔案:

        wKiom1hafQfjQrBfAAAKKUisYr0146.png

    使用openssl version命令也可以看到我們系統上的安裝的openssl軟體的版本號:

        wKioL1hafYjgNP88AAALz1CsNiU571.png

·openssl命令列工具的子命令

    1,speed子命令

        該子命令用於測試openssl對各種支援的加密演算法的加密速度,會測試每一種加密演算法在我們主機上的加密速度,這種速度還可以用來評估我們當前系統的加密效能,該子命令預設會計算所有加密演算法的速度:

        wKiom1haft6B_DszAABAiK1ym_4303.png

    2,enc子命令

        該子命令用於加密,用法格式:

        openssl enc -加密演算法 -in 要加密的檔案 -out 加密後的檔名

            -e選項表示加密,但是該命令預設就是加密,不用特地指定該選項

            -d選項表示解密

            -k選項表示指定加密金鑰,如果沒有該選項,系統會提示我們輸入密碼

            -salt選項表示實現更高的安全性

            -a選項表示對純文字進行base64編碼

        wKioL1hahlvT28efAAA5DZ8kBOQ020.png

        解密:

            wKioL1haiBbS1KJGAAA5pV4ZsVQ328.png

    3,dgst子命令

        該子命令用於計算資料的特徵碼,用法格式:

        openssl dgst -單向加密演算法 原始資料

        wKioL1haiJHyfdUTAAAQeMEswy0296.png

        md5sum命令也可以用來計算資料的基於md5單向加密演算法的資料特徵碼:

        wKiom1haiSjBtbH-AAAOHsZwgvE886.png

        sha1sum命令也可以用來計算資料基於sha1單向加密演算法的資料特徵嗎:

        wKiom1haiZCj70t6AAAO2Uq6mpQ668.png

    4,passwd子命令

        該子命令用於生成一段密碼段。

        openssl passwd -1,表示使用md5演算法計算生成的密碼段的特徵碼:

        wKioL1haisfQelNHAAAjbfdqRAc782.png

        生成的密碼段和我們儲存在shadow檔案中的條目的格式很相似:

        wKiom1hai0zzNY3_AAAvTK9tkWM229.png

        頭兩個$符之間是使用的加密演算法,後兩個$符之間是salt,有了salt的幫助,我們連續兩次生成的特徵碼就會不同:

        wKiom1hai_fzB84fAAAygPEwn0c232.png

        salt在密碼段中的作用就是去攪渾密碼的,它存在的意義就是防止有人去反推我們的密碼,按照單向加密演算法的特性,輸入一樣,那麼輸出一定一樣,為了保證使用單向加密演算法生成的密碼不一樣,我們就向生成的密碼段中加入了salt,但是salt並不影響我們去獲取最終的結果,因為我們每次生成密碼段的時候都會使用salt,但是有了salt,我們的密碼就無法被別人反推,因為每次生成的salt是不一樣的。

        還可以使用-salt選項來指定所加的salt:

        wKiom1hajgKB0oNIAAA1BN--5wk431.png

    5,rsautil(RSA utility)子命令

        該子命令用於進行非對稱加密,openssl同樣支援RSA加密演算法,rsa不但支援資料加密而且還支援身份認證,但是dsa只支援身份認證。

        用法格式:openssl rsautil -in 加密檔案 -out 加密後的檔名 -inkey(指定金鑰)

    6,rand子命令

        該子命令用來生成偽隨機數,是一個偽隨機數生成工具,用法格式:

        openssl rand -base64 任意數字

        使用該命令就可以生成一堆隨機數,我們如果想使用一堆隨機數來當做我們的密碼就可以使用該命令來實現:

        wKioL1hakH2ieXh0AABKeIXn1-8864.png 

·openssl實現私有CA

    帶有加密解密過程的網際網路通訊都得使用到證書,如果我們想要在公司內部模擬實現一個https伺服器進行通訊的話,那我們就得給我們的web伺服器發一個證書才可以,我們可以使用openssl來自己製作一個私有CA,一個CA想要給別人發放證書,那麼首先CA自己得先有一個自己的證書,所以使用openssl實現私有CA的步驟如下:

    第一步,先生成一對金鑰

       生成一對rsa私鑰的命令是:

       openssl genrsa(generate rsa)->該命令用於生成rsa私鑰

       因為公鑰是從私鑰中提取出來的,公鑰源自於私鑰,只要有了私鑰就會有公鑰,該命令就是幫助我們生成一個rsa私鑰,而且該命令可以跟上數字來指定私鑰的長度,預設長度是512位:

        wKiom1haknrgqNg8AABZdhCFLjU737.png

    我們可以使用輸出重定向儲存生成的rsa私鑰:

        wKiom1hwxIWhPA_SAAAWLWFWG4c021.png

        也可以使用-out選項將rsa私鑰儲存在某個檔案中:

        wKiom1hwxOzC75xeAABtv4hsPDM645.png

        私鑰檔案在我們本機中一般很少加密存放,但是私鑰檔案的安全性有很重要,所以我們可以通過設定私鑰檔案許可權的方法來保證私鑰檔案的安全性。

        Tips:

        在當前shell命令列中使用括號括起來的命令,無論多少命令,這些命令都將會在當前shell的子shell中執行,而且執行完成之後,子shell就會退出,我們可以利用shell的這個特點來生成私鑰檔案的預設許可權,而不會改變當前shell環境中的umask:

        wKioL1hwxtfw_19mAAAseiszZVE111.png    

        將公鑰從私鑰當中提取出來的命令:

        wKiom1hwx_PiTFDUAAArmqpGy6I827.png

    第二步,生成自簽署的證書

        使用openssl的req(request)子命令來生成一個自簽署