非對稱加密和證書總結

轉載請註明文章來源: https://tlanyan.me/asymmetric...

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

加密方式

密碼學是涉及數學、電子信息、計算機等多學科的一門重要學科,是現代互聯網安全的基石,也是目前如火如荼的區塊鏈技術的安全保障。歸納來講,加密方式可歸結以下:node

1、 不可逆加密nginx

信息摘要(Message Digest)和安全散列(Secure Hash)算法屬於此類,常見的算法包括MD五、SHA一、PBKDF二、bcrypt等。此類算法可將任意大小的原始數據變換成規定長度的輸出,即獲取內容的數字指紋,經常使用於校驗原始內容是否被篡改。這類算法的主要特色是:git

  1. 不可逆性。除非窮舉等手段,原則上不存在根據密文推斷出原文的算法;
  2. 雪崩效應。對輸入數據敏感,原始內容的極小改動會形成輸出的大差別;
  3. 防碰撞性。原則上很難找到兩組相同的原文,通過加密後密文相同。

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

哈希算法的一個變種是HMAC(Hash-based Message Authentication Code)算法,用於解決身份認證和防抵賴。HMAC算法的輸入爲一個密鑰(通訊雙方共享)、一種哈希算法(常爲經典哈希算法)和原始數據,輸出的內容格式取決於所採用的哈希算法。因爲只有通訊雙方知曉密鑰,簽名正確的狀況下可確認信息就是由對方發出。算法

2、 可逆加密shell

哈希算法的簽名可保證通訊中的數據不被篡改,可逆加密算法是還原出明文的關鍵。可逆加密算法可分紅三類:api

  1. 基於算法的加密算法,也被稱爲古典加密算法,如http認證中的base64,比特幣生成地址用的base58(公開的算法也可稱做編碼方式)。這類算法主要對原始內容進行置換和替換獲得密文,安全性依賴於算法是否外泄;
  2. 對稱加密算法,加密和解密使用同一個密鑰。對稱加密算法的出現標誌密碼學進入現代密碼學階段,密文的安全性從依賴於算法轉向依賴於密鑰。常見的對稱加密算法有DES、3DES、AES;
  3. 非對稱加密算法,加密和解密使用不一樣的密鑰。非對稱加密算法開創了密碼學的里程碑,解決了對稱加密過程當中密鑰分發的安全問題,被認爲現代密碼學最偉大的發明。常見的算法有RSA、DH(Diffie-Hellman)、橢圓曲線算法(Elliptic curve cryptography,ECC)。

非對稱算法設計巧妙,但實際中要結合對稱加密使用。緣由是某些算法不能加解密(DH、DSA),或者效率過低(RSA),或者能處理的數據大小有限制(RSA)。而對稱加密算法的有點是速度快,加密強度高。經常使用非對稱算法得到共享密鑰,以後用對稱加密處理數據。瀏覽器

本文的重點是非對稱加密及其衍生概念,下面逐一介紹。安全

公鑰、私鑰和證書

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

# 放開私鑰權限
chmod 644 ~/.ssh/id_ras
# 鏈接服務器
ssh server
# openssh 客戶端出現以下報錯:
Permissions 0644 for '/home/tlanyan/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/tlanyan/.ssh/id_rsa": bad permissions
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

私鑰和公鑰的做用通常分爲兩種:

  1. 公鑰加密,私鑰解密,主要用於通訊;
  2. 私鑰簽名,公鑰驗證,主要用於簽名。

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

理論上有了公鑰和密鑰,雙方就能夠安全無礙的通訊,那常說的證書是怎麼回事?

證書,顧名思義,就是證實的文件。例如瀏覽器和tlanyan.me服務器通訊,瀏覽器怎麼知道對方就是tlanyan.me對應的服務器呢?在不可信的網絡下通訊,中立的第三方做用就顯現出來了。權威的第三方中立機構(同常是Certificate Authority, CA)給tlanyan.me的持有者頒發證書,證實其就是域名全部人。服務器收到請求後將證書一塊兒發送出去,瀏覽器對證書進行檢查,並向第三方詢問是否爲真,確認無誤後,就能夠放心的通訊了。

證書包含公鑰,因此拿到證書意味着就拿到了對方的公鑰。幾乎全部的瀏覽器都會都證書進行校驗,以確保網頁通訊中的安全。使用自簽發的證書,或者過時、與請求主機不符合的證書,都會致使瀏覽器發出安全警告,提醒用戶潛在的風險。

<img src="https://tlanyan.me/wp-content...; alt="" width="620" height="208" class="aligncenter size-large wp-image-2635" />

CURL等第三方庫通常不會對證書進行檢查,服務器交互時如何確保通訊的對方是真李逵而非李鬼?

答案是客戶端預先存一份服務器證書,通訊時校驗服務端發來的證書與本地的是否一致。若是不一致,則說明遇到了中間人攻擊,或預設的通訊方實體已經變動。以前作微信支付的對接,不理解微信的服務器證書的做用,後來才理解其深意。

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

  1. DNS污染,返回錯誤的IP地址;
  2. 直接把域名的全部IP封掉;
  3. 根據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頁面描述了其能力範圍:

The openssl program is a command line tool for using the various cryptography functions of
OpenSSL's crypto library from the shell.  It can be used for

    o  Creation and management of private keys, public keys and parameters
    o  Public key cryptographic operations
    o  Creation of X.509 certificates, CSRs and CRLs
    o  Calculation of Message Digests
    o  Encryption and Decryption with Ciphers
    o  SSL/TLS Client and Server Tests
    o  Handling of S/MIME signed or encrypted mail
    o  Time Stamp requests, generation and verification

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

md5:

echo tlanyan | openssl md5
## 結果與下條命令相同
echo tlanyan | md5sum

aes加解密:

# 用法
# openssl aes-128-cbc -e -in 加密文件 -out 解密文件 -pass pass:密碼
# 例如
echo tlanyan > input
openssl aes-128-cbc -e -in input -out output -pass pass:1234567890abcdef
# 加密的內容在output中
# 解密
openssl aes-128-cbc -d -in output -o origin -pass pass:1234567890abcdef

生成CSR、簽發證書:

# 先生成csr和私鑰
# 注意使用-nodes選項,不然私鑰會有密碼,用在nginx啓動時須要手動輸入
openssl req -new -out tlanyan.csr -newkey rsa:2048 -nodes -keyout tlanyan.priv.key
# 接下來的交互裏填入一些基本信息,完畢後會生成tlanyan.csr和tlanyan.priv.key兩個文件
# csr的格式以下:
# -----BEGIN CERTIFICATE REQUEST-----
# xxxx
# -----END CERTIFICATE REQUEST-----
# 密鑰文件的格式相似
# 有了csr,接下來爲本身簽發證書
openssl req -x509 -sha256 -nodes -days 365 -in tlanyan.csr -key tlanyan.priv.key -out tlanyan.crt
# 命令結束後,目錄中出現tlanyan.crt的證書文件

# 校驗密鑰
openssl rsa -in tlanyan.priv.key --check
# 校驗csr
openssl req -in tlanyan.csr -verify
# 校驗證書
openssl x509 -in tlanyan.crt -text -noout

轉換各類不一樣格式的證書:

# 將pem格式轉換成pfx/p12格式
openssl pkcs12 -export -out tlanyan.pfx -inkey tlanyan.priv.key -in tlanyan.crt
# 將pfx格式轉換成pem格式
openssl pkcs12 -in tlanyan.pfx -out tlanyan.cer -nodes
# 生成的tlanyan.cer文件包含了證書和公鑰,對應導入前的tlanyan.crt和tlanyan.priv.key兩個文件

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

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

總結

本文介紹了非對稱加密和證書的相關概念,並演示了openssl命令的一些用法。文章涉及內容較多,理解上稍顯難度。另外本文參考了很多文章,理解上的不到之處敬請指正。

感謝閱讀!

參考

  1. https://coolshell.cn/articles...
  2. http://www.tldp.org/HOWTO/SSL...
  3. https://legacy.gitbook.com/bo...
  4. https://www.integralist.co.uk...
  5. https://rakhesh.com/infrastru...
  6. https://www.sslshopper.com/wh...
  7. http://www.cnblogs.com/jeremy...
  8. https://www.sslshopper.com/ss...
  9. https://docs.oracle.com/cd/E3...
相關文章
相關標籤/搜索