非對稱加密與安全證書看這一篇就懂了

IT技術精選文摘發表於2018-07-01

640?wx_fmt=gif

前幾日做支付對接時,被對方文件中的加密方式搞暈乎了一會。意識到證照加密方面的理解不夠深入,事後查閱參考資料補習一波。本文是根據期間的學習,以及長期以來的實踐做出的總結。

加密方式

密碼學是涉及數學、電子資訊、計算機等多學科的一門重要學科,是現代網際網路安全的基石,也是目前如火如荼的區塊鏈技術的安全保障。概括來說,加密方式可歸結為不可逆加密與可逆加密。

不可逆加密

資訊摘要(Message Digest)和安全雜湊(Secure Hash)演算法屬於此類,常見的演算法包括 MD5、SHA1、PBKDF2、bcrypt 等。此類演算法可將任意大小的原始資料變換成規定長度的輸出,即獲取內容的數字指紋,常用於校驗原始內容是否被篡改。這類演算法的主要特點是:

  • 不可逆性。除非窮舉等手段,原則上不存在根據密文推斷出原文的演算法;

  • 雪崩效應。對輸入資料敏感,原始內容的極小改動會造成輸出的大差異;

  • 防碰撞性。原則上很難找到兩組相同的原文,經過加密後密文相同。

左耳朵耗子的“RSYNC 的核心演算法”介紹了 MD5 演算法在 rsync 中的具體應用。MD5 和 SHA1 已經被證實不安全(王小云教授在04年找到 MD5 迅速碰撞方法,谷歌在17年完成了 SHA1 的第一次碰撞),實踐中建議至少用 SHA-256 演算法,或採用對算力不敏感的 scrypt、Argon2 等演算法。

雜湊演算法(安全雜湊)的一個變種是 HMAC(Hash-based Message Authentication Code)演算法,用於解決身份認證和防抵賴。HMAC 演算法的輸入為一個金鑰(通訊雙方共享)、一種雜湊演算法(常為經典雜湊演算法)和原始資料,輸出的內容格式取決於所採用的雜湊演算法。由於只有通訊雙方知曉金鑰,所以可確認資訊就是由對方發出。

可逆加密

雜湊演算法可保證通訊中的資料不被篡改,而可逆加密演算法是還原出明文的關鍵。可逆加密演算法可分成三類:

  • 基於演算法的加密演算法,也被稱為古典加密演算法,如 HTTP 認證中的 base64,比特幣生成地址用的 base58(公開的演算法也可稱作編碼方式)。這類演算法主要對原始內容進行置換和替換得到密文,安全性依賴於演算法是否外洩;

  • 對稱加密演算法,加密和解密使用同一個金鑰。對稱加密演算法的出現標誌密碼學進入現代密碼學階段,密文的安全性從依賴於演算法轉向依賴於金鑰。常見的對稱加密演算法有 DES、3DES、AES;

  • 非對稱加密演算法,加密和解密使用不同的金鑰。非對稱加密演算法開創了密碼學的里程碑,解決了對稱加密過程中金鑰分發的安全問題,被認為現代密碼學最偉大的發明。常見的演算法有 RSA、DH(Diffie-Hellman)、橢圓曲線演算法(Elliptic curve cryptography,ECC)。

非對稱演算法設計巧妙,但實際中要結合對稱加密使用。原因是某些演算法不能加解密(DH、DSA),或者效率太低(RSA),或者能處理的資料大小有限制(RSA)。而對稱加密演算法的有點是速度快、加密強度高。常用非對稱演算法獲得共享金鑰,之後用對稱加密處理資料。本文的重點是非對稱加密及其衍生概念,下面逐一介紹。

公鑰、私鑰和證照

除演算法外,非對稱加密中另外兩個重要的概念是公鑰和私鑰。公鑰對外公開,任何人均可持有和使用;私鑰自行保管,其安全性是通訊安危的關鍵。例如 OpenSSH 客戶端預設會拒絕用許可權開放的私鑰連線伺服器,會出現如下提示:

640?wx_fmt=png

私鑰和公鑰的作用一般分為兩種:

  • 公鑰加密,私鑰解密,主要用於通訊;

  • 私鑰加密(簽名),公鑰解密(驗證),主要用於數字簽名。

本次做支付對接時,對其演算法疑慮的地方是需要用到私鑰,按理要用對方的公鑰加密才對啊!後來意識到是用作資料簽名,用客戶端的私鑰是正確的。

理論上有了公鑰和金鑰,雙方就可以安全無礙的通訊,那常說的證照是怎麼回事?

證照,顧名思義,就是證明的檔案。例如瀏覽器和 tlanyan.me 伺服器通訊,瀏覽器怎麼知道對方就是 tlanyan.me 對應的伺服器呢?在不可信的網路下通訊,中立的第三方作用就顯現出來了。權威的第三方中立機構( Certificate Authority, CA)收到 tlanyan.me 持有者的證照請求並核驗資訊後,將持有者的名稱、公鑰與 CA 用私鑰生成的數字簽名等資訊寫成證照頒發給申請者。

使用者與伺服器通訊時,伺服器收到請求後將證照發給瀏覽器,瀏覽器對證照進行檢查(是否過期,能否用 CA 的公鑰驗證簽名等),並向第三方詢問是否為真(是否被吊銷等),確認無誤後,就可以放心地通訊了。

證照包含公鑰,所以拿到證照意味著就拿到了對方的公鑰。幾乎所有的瀏覽器都會對證照進行校驗,以確保網頁通訊中的安全。使用自簽發的證照,或者過期、與請求主機不符合的證照,都會導致瀏覽器發出安全警告,提醒使用者潛在的風險,如下圖所示:

640?wx_fmt=png

CURL 等第三方庫一般不會對證照進行檢查,那麼與伺服器互動時如何確保通訊的對方是真李逵而非李鬼?

答案是客戶端預先存一份伺服器證照(證照從官網、對方郵件等可信渠道獲取),通訊時校驗服務端發來的證照與本地預存的是否一致。如果不一致,則說明遇到了中間人攻擊,或預設的通訊方實體已經變更,客戶端應對這種情況進行處理,例如列印警告或中斷通訊。

而在校驗一致的情形下,客戶端用證照的公鑰加密資訊發往服務端,如果對方是中間人,其沒有通訊方的私鑰就無法解密資訊,也會造成通訊失敗。所以在私鑰不洩露的前提下,內建對方證照是解決中間人攻擊的最有效辦法,因為 CA 也有可能作假(參考 CNNIC),而瀏覽器需要與成千上萬個網站通訊,不可能所有站點證照都內建,所以使用 CA 比較合理。之前做微信支付的對接,不理解微信伺服器證照的作用,後來才理解其深意。

許多國外網站使用 HTTPS,照樣倒在國內偉大的防火牆之下。根據 HTTPS 加密通訊的特點,同時 CA 加持,原則上牆是不可能知道通訊的內容。那麼在 HTTPS 通訊時,牆是怎麼識別出來並阻斷的?個人認為有三個可切入的點:

  • DNS 汙染,返回錯誤的 IP 地址;

  • 直接把域名的所有 IP 封掉;

  • 根據 HTTPS 的互動流程,客戶端和伺服器協商金鑰階段的資料均為明文,獲取金鑰後才會加密資料(包括 URL)。協商階段的證照必然出現網站主機名,防火牆在這個階段可識別並阻斷。

以上想法出自個人猜測。

總結:通訊的私鑰應該總是被妥善保管,在不可靠的網路環境下通訊,證照能避免中間人攻擊。

CSR、PEM、keystore 等

蘋果開發會接觸到 CSR、證照,安卓開發會用到 keystore,web 開發會用到 PEM、金鑰、證照、jks 等。這些都是什麼?

CSR(Certificate Sign Request)、公鑰、金鑰和證照歸屬為一類。CSR 用來獲取證照,包含申請人的公鑰、郵件等證明身份的資訊。證照頒發機構(可以是自己)收到 CSR 後簽發證照,生成的證照中包含公鑰、有效期、持有人等資訊。私鑰可單獨生成,也可在生成 CSR 的同時生成。整個過程中,私鑰應當都要被妥善保管,不能洩露。

keystore、PEM、cer/crt、key 等檔案儲存格式可歸為一類。Java KeyStore(檔案字尾 .keystore 或 .jks)是 Java 常用的儲存金鑰和證照的檔案格式,需要設定檔案密碼、別名和別名密碼,安卓打包和部署 Tomcat 時會用到;PEM(Privacy Enhanced Mail)以文字形式存放私鑰和證照(鏈);cer/crt 和 key 分別用來存放證照和金鑰;另外一種常見的格式是 pfx 和 p12,同 jks 格式,這類檔案一般是二進位制,訪問需要密碼。

PKI(Public key infrastructure)體系構建在公鑰加密基礎之上,主要解決證照的頒發和管理問題。證照管理中應用廣泛的兩個標準是 X509 和 PKCS。遵循 X509 標準的證照檔案結尾多為 PEM、der、crt 等;遵循 PKCS 標準的證照常用字尾名是 pfx、p12 等。

本次對接暈乎的第二個地方是一處地方讀取金鑰需要密碼,另一處直接讀取。根據儲存格式可知原因:訪問遵循 PKCS#12 標準的 pfx 檔案需要密碼,遵循 X509 規範的 PEM 檔案則可直接檢視內容。

OpenSSL

OpenSSL 是通用的加密庫,openssl 是基於它的命令列工具,上文提到的內容基本都在其功能範圍內。另一個與 openssl 類似的工具是 GPG(GNU Privacy Guard),區別是 OpenSSL 遵循 X509 標準,GPG 遵循 OpenPGP 標準。兩者加密的檔案在格式上有所差異,無法解開對方加密過的檔案。OpenSSL 和 GPG 內建在大多數 *nix 系統中,可直接使用。

以下示例基於 OpenSSL,GPG 的用法可檢視文中最後的參考文獻。

openssl 命令的 man 頁面描述了其能力範圍:

640?wx_fmt=png

接下來看一些簡單的 openssl 使用示例:

md5:

640?wx_fmt=png

aes 加解密:

640?wx_fmt=png

生成 CSR、簽發證照:

640?wx_fmt=png

640?wx_fmt=png

轉換各種不同格式的證照:

640?wx_fmt=png

pem 和 jks 的格式轉換太過複雜, 具體請看 Oracle 的文件。

以上演示的只是 openssl 工具包中的極小一部分命令。更多的用法請參考官方文件。

總結

本文介紹了非對稱加密和證照的相關概念,並演示了 openssl 命令的一些基本用法,希望能夠幫助到對這方面內容有疑惑的讀者。文章涉及內容較多,理解上稍顯難度。另外本文參考了不少文章,理解上的不到之處敬請指正。

感謝閱讀!

公眾號推薦:

640?wx_fmt=jpeg

640?wx_fmt=jpeg


相關文章