前言
我們?cè)谧龀绦蜷_發(fā)的過程中,經(jīng)常會(huì)遇到一些需求,是需要對(duì)某些敏感數(shù)據(jù)進(jìn)行安全傳輸和保密的。比如 用戶的登錄和注冊(cè)操作,用戶的登錄態(tài)維護(hù)、以及接口簽名、敏感數(shù)據(jù)加密傳輸?shù)鹊?。那么這篇文章將會(huì)首先介紹相關(guān)的比較常見的加密算法的概念,其次我會(huì)對(duì)一些比較大家常見的名詞做一下解釋,最后我會(huì)再討論一下根據(jù)具體場(chǎng)景下的需求的相應(yīng)解決方案。
本文不會(huì)對(duì)加密算法的數(shù)學(xué)原理,以及各個(gè)算法的優(yōu)點(diǎn)缺點(diǎn)做深入的解釋。
寫作目的
- 了解加密算法相關(guān)知識(shí)概念和使用流程,加深對(duì)密碼學(xué)的初步印象。
- 提供涉及到數(shù)據(jù)安全相關(guān)需求的解決方案參考,適合新手參考。
- 加深自己對(duì)數(shù)據(jù)加密知識(shí)的基礎(chǔ)理解

正文
對(duì)稱加密算法
概念
加密算法的對(duì)稱和非對(duì)稱性,其實(shí)很好理解。就是加密過程和解密過程都使用的是同一個(gè)密鑰的算法就叫做對(duì)稱加密算法。
常見的對(duì)稱加密算有:AES,DES,3DES等。
優(yōu)點(diǎn)
- 加密速度快,效率高、計(jì)算量小。
缺點(diǎn)
- 加密和解密使用的是同一個(gè)密鑰,安全性低。
- 密鑰數(shù)量多,管理難度高。比如服務(wù)端要和N個(gè)客戶端進(jìn)行安全通信,那么需要管理N對(duì)密鑰。
非對(duì)稱加密算法
概念
非對(duì)稱加密算法指的就是加密和解密的過程使用的是不同的密鑰,一般會(huì)在使用非對(duì)稱加密算法的時(shí)候,生成一對(duì)“密鑰對(duì)”。包含一個(gè)“公鑰”和一個(gè)“私鑰”。公鑰是公開給外部使用的,私鑰則是信息接收方自己保留。
常見的非對(duì)稱加密算法有:DH (又稱“Diffie–Hellman"算法)、ECC(橢圓曲線加密算法)、RSA。
比如常見的情況就是,客戶端要和服務(wù)端進(jìn)行通信,客戶端要發(fā)送敏感數(shù)據(jù)給到服務(wù)端。服務(wù)端會(huì)生成密鑰對(duì),將私鑰自己保留,公鑰發(fā)放給所有與之通信的客戶端。客戶端利用公鑰將數(shù)據(jù)加密之后發(fā)送給服務(wù)端,服務(wù)端解密獲取明文數(shù)據(jù)。
優(yōu)點(diǎn)
- 安全性高,公鑰加密的數(shù)據(jù),只有私鑰才能解密。其他密鑰都不行。
- 密鑰管理難度大大降低,對(duì)比于對(duì)稱加密算法。通信的一方只需要保管好自己的私鑰,就能和任意個(gè)數(shù)的另一方進(jìn)行通信。對(duì)方只需要拿指定的公鑰進(jìn)行數(shù)據(jù)加密即可。
缺點(diǎn)
- 加密和解密花費(fèi)時(shí)間相比于對(duì)稱加密算法來說會(huì)長(zhǎng)一些,只適合對(duì)少量數(shù)據(jù)進(jìn)行加密。
可逆加密算法
概念
可逆加密算法指的是,明文數(shù)據(jù)通過一系列指定的函數(shù)加密之后得到密文,也能通過一定的函數(shù)將密文還原成明文的算法。
常見的可逆加密算法有:前文所指的對(duì)稱和非對(duì)稱大都是可逆的加密算法。畢竟 大部分場(chǎng)景下 我們是需要得到解密之后的明文數(shù)據(jù)的。
特點(diǎn)
- 可以恢復(fù)回明文數(shù)據(jù),適用于那些需要得到明文數(shù)據(jù)的場(chǎng)景。
不可逆加密算法
概念
不可逆加密算法指的是,明文數(shù)據(jù)經(jīng)過不可逆加密算法的加密之后,得到的密文數(shù)據(jù)很難甚至無法恢復(fù)回原來的明文數(shù)據(jù)。
舉個(gè)簡(jiǎn)單的例子,假設(shè)一個(gè)明文數(shù)據(jù)為任意的一個(gè)數(shù)字278,我們的加密算法為將此數(shù)字乘以698758。得到的結(jié)果就是密文數(shù)據(jù),那么正向的乘法很容易計(jì)算,但是逆向需要將乘法的結(jié)果因式分解回原來的數(shù)字就沒那么容易了。特別是大素?cái)?shù)的因式分解。有的不可逆加密算法就是參考類似的這樣的數(shù)學(xué)原理,找到一種正向容易反向難得的算法過程來實(shí)現(xiàn)不可逆加密算法。
常見的不可逆加密算法有:MD5、SHA系列算法(SHA128,SHA256,SHA512)、HMAC系列算法(HMAC-SHA256,HMAC-SHA512)。
優(yōu)點(diǎn)
- 加密密文不可逆,無法還原或者很難還原明文數(shù)據(jù)
- 壓縮性,任意長(zhǎng)度的數(shù)據(jù)加密之后都是固定的
- 抗修改性,對(duì)原數(shù)據(jù)的微小改動(dòng),都會(huì)使得加密后的數(shù)據(jù)不一致
- 抗碰撞性,想要找到兩個(gè)不一樣的明文加密得到同樣的密文數(shù)據(jù)很難。
缺點(diǎn)
- 比較明顯的缺點(diǎn)就是,不可逆。無法恢復(fù)成明文數(shù)據(jù)。只適用于數(shù)字簽名,身份驗(yàn)證相關(guān)的場(chǎng)景
常見網(wǎng)絡(luò)安全相關(guān)名詞解釋
消息摘要
消息摘要是在數(shù)字簽名中經(jīng)常使用的一個(gè)功能,它的主要實(shí)現(xiàn)是使用一個(gè)哈希單向散列函數(shù)將原文進(jìn)行處理得到一個(gè)固定長(zhǎng)度的字符串,我們稱這個(gè)字符串就是原文的”消息摘要“。也可以叫做”數(shù)字指紋“。利用了哈希單向散列函數(shù)的壓縮性和康修改性。比如我們經(jīng)常對(duì)文件的上傳和下載進(jìn)行MD5哈希函數(shù)處理,使用一個(gè)MD5值用于鑒別當(dāng)前文件是否有被篡改,也可以用于判斷文件內(nèi)容是否重復(fù)。比如判斷是否文件重復(fù)上傳,以及”秒傳“等功能的實(shí)現(xiàn)也是借助MD5來判斷服務(wù)器中是否存儲(chǔ)有一樣的文件內(nèi)容。
數(shù)字簽名
數(shù)字簽名(又稱公鑰數(shù)字簽名)是只有信息的發(fā)送者才能產(chǎn)生的別人無法偽造的一段數(shù)字串,這段數(shù)字串同時(shí)也是對(duì)信息的發(fā)送者發(fā)送信息真實(shí)性的一個(gè)有效證明。它是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領(lǐng)域的技術(shù)來實(shí)現(xiàn)的,用于鑒別數(shù)字信息的方法。一套數(shù)字簽名通常定義兩種互補(bǔ)的運(yùn)算,一個(gè)用于簽名,另一個(gè)用于驗(yàn)證。數(shù)字簽名是非對(duì)稱密鑰加密技術(shù)與數(shù)字摘要技術(shù)的應(yīng)用(來自百度百科的詞條解釋)
常見的邏輯是:信息的發(fā)送者,先使用<u>消息摘要技術(shù)</u>對(duì)信息進(jìn)行壓縮,生成一個(gè)信息摘要。然后采用<u>私鑰</u>對(duì)消息摘要進(jìn)行加密。加密后的數(shù)據(jù)就叫做”<u>數(shù)字簽名</u>“。然后發(fā)送者將”<u>數(shù)字簽名</u>“和原文信息一起發(fā)送給接收方,接收方收到信息后,利用<u>公鑰</u>對(duì)數(shù)字簽名進(jìn)行解密,得到發(fā)送過來的消息摘要。再利用同樣的消息摘要技術(shù)對(duì)原文進(jìn)行壓縮得到一個(gè)接收方自己生成的消息摘要,然后和發(fā)送方發(fā)送的那份進(jìn)行對(duì)比。如果發(fā)現(xiàn)數(shù)據(jù)不一致,則證明信息內(nèi)容被篡改。如果一致則證明信息沒有被篡改,如果能夠正常解密則證明消息確實(shí)由發(fā)送方發(fā)送,否則認(rèn)為是第三方偽造發(fā)送動(dòng)作。
數(shù)字證書
數(shù)字證書主要的作用就是解決數(shù)字簽名過程中存在的某些不安全情況,比如驗(yàn)證方無法判斷公鑰是否是對(duì)方的公鑰,或者存儲(chǔ)的公鑰被替換成欺騙方的公鑰等。而數(shù)字證書就是通過一個(gè)受信的第三方機(jī)構(gòu)進(jìn)行公鑰的頒發(fā),申請(qǐng)人可以向CA機(jī)構(gòu)申請(qǐng)一個(gè)數(shù)字證書,將自己的公鑰已經(jīng)個(gè)人信息注冊(cè)到CA證書機(jī)構(gòu)。CA證書機(jī)構(gòu)進(jìn)行各個(gè)申請(qǐng)人的公鑰和相關(guān)信息進(jìn)行管理,通過機(jī)構(gòu)的私鑰對(duì)申請(qǐng)人的公鑰和信息進(jìn)行加密得到一個(gè)”數(shù)字證書“。然后當(dāng)通信雙方進(jìn)行通信的時(shí)候,發(fā)送方將發(fā)送三個(gè)東西,一個(gè)是信息原文,一個(gè)是數(shù)字簽名,一個(gè)是數(shù)字證書。接收方拿到CA機(jī)構(gòu)的公鑰(一般已經(jīng)內(nèi)置于瀏覽器中)對(duì)數(shù)字證書進(jìn)行解密,得到公鑰和公鑰發(fā)布方的相關(guān)信息。然后使用公鑰對(duì)數(shù)字簽名進(jìn)行解密得到消息摘要,最后進(jìn)行判斷。這里我們就可以對(duì)這個(gè)公鑰進(jìn)行充分的信任,畢竟是可信機(jī)構(gòu)頒發(fā)的數(shù)字證書。并且經(jīng)過私鑰加密,攻擊者無法獲取信息和修改。
CA
CA就是CA證書的頒布機(jī)構(gòu),就是一個(gè)數(shù)字證書管理中心,可以這么理解。
中間人攻擊
中間人攻擊(Man-in-the-MiddleAttack,簡(jiǎn)稱“MITM攻擊”)是一種“間接”的入侵攻擊,這種攻擊模式是通過各種技術(shù)手段將受入侵者控制的一臺(tái)計(jì)算機(jī)虛擬放置在網(wǎng)絡(luò)連接中的兩臺(tái)通信計(jì)算機(jī)之間,這臺(tái)計(jì)算機(jī)就稱為“中間人”。(來自百度百科詞條)
比如有:會(huì)話劫持,DNS欺騙,偽造SSL證書等。
會(huì)話劫持的原理指的是,攻擊者通過分析客戶端和服務(wù)端直接通信的網(wǎng)絡(luò)數(shù)據(jù)包,比如從HTTP連接的cookie中拿到雙方通信的會(huì)話,然后使用此會(huì)話進(jìn)行登錄目標(biāo)網(wǎng)站完成操作。
DNS欺騙指的是,攻擊者對(duì)客戶端本地的DNS域名解析進(jìn)行污染。修改DNS解析域名的映射到攻擊者本機(jī),這樣當(dāng)客戶端進(jìn)行域名訪問的時(shí)候就會(huì)將數(shù)據(jù)轉(zhuǎn)發(fā)到攻擊者的IP上去。由攻擊者進(jìn)行控制和轉(zhuǎn)發(fā)相應(yīng)信息。
偽造SSL證書也是類似的原理,通過偽造一對(duì)RSA的公私鑰對(duì),然后與客戶端和服務(wù)端進(jìn)行雙向SSL認(rèn)證。變成雙方數(shù)據(jù)通信的中間人。
JWT
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object (來自jwt.io官網(wǎng)對(duì)JWT的介紹)
簡(jiǎn)單來說就是JSON格式的Token字符串。里面包含三個(gè)部分。分別是:header、payload、signature。
header主要描述的內(nèi)容是算法類型和token格式。
For example:
{
"alg": "HS256",
"typ": "JWT"
}
payload主要描述的內(nèi)容是具體的傳輸數(shù)據(jù),以一個(gè)JSON對(duì)象的形式出現(xiàn)。里面也可以有自定義的數(shù)據(jù)字段以及一些官方標(biāo)準(zhǔn)提供的數(shù)據(jù)字段。
- iss (issuer):簽發(fā)人
- exp (expiration time):過期時(shí)間
- sub (subject):主題
- aud (audience):受眾
- nbf (Not Before):生效時(shí)間
- iat (Issued At):簽發(fā)時(shí)間
- jti (JWT ID):編號(hào)
除了官方字段,你還可以在這個(gè)部分定義私有字段,下面就是一個(gè)例子。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
最后的signature簽名則是通過之前約定的加密算法,然后對(duì)前兩個(gè)部分進(jìn)行base64URLEncode,部分之間通過“點(diǎn)號(hào)”拼接得到。
For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
常見數(shù)據(jù)安全場(chǎng)景
用戶進(jìn)行系統(tǒng)的注冊(cè)、登錄、資源訪問
我們先說一下注冊(cè)的場(chǎng)景,注冊(cè)的時(shí)候主要需要防范的出現(xiàn)的情況是,用戶注冊(cè)的用戶名密碼等敏感數(shù)據(jù)明文被攻擊者獲取,然后攻擊者可以去自由登錄進(jìn)行訪問系統(tǒng)資源。
那么我們可以采用非對(duì)稱加密的方式來加密明文,然后服務(wù)端進(jìn)行密文的解密得到數(shù)據(jù)。攻擊者沒有私鑰,無法解密得到明文信息。
還有的情況就是,攻擊者能夠截取服務(wù)器數(shù)據(jù)庫,獲得明文密碼?;蛘呙魑拿艽a存儲(chǔ)在數(shù)據(jù)庫,被內(nèi)部人員等等偷偷泄露。所以用戶的敏感數(shù)據(jù)一般都是直接密文存儲(chǔ)在數(shù)據(jù)庫中的。但是哈希密文也不一定可靠,攻擊者可以根據(jù)密文進(jìn)行推測(cè)和計(jì)算等等的方式去破解哈希,比如字典攻擊和暴力攻擊,查表法、反向查找法、彩虹表等等。
比如MD5哈希的安全性就不可靠
所以我們可以采用相對(duì)安全的哈希加密算法SHA256,SHA512等,再搭配隨機(jī)鹽值來降低哈希密碼被破解的可能性。
下面是我畫的注冊(cè)用例的時(shí)序圖

總結(jié)
需要解決的問題:用戶敏感數(shù)據(jù)明文被截獲、明文密碼在數(shù)據(jù)庫被泄露
解決方案:非對(duì)稱加密算法進(jìn)行數(shù)據(jù)傳輸、長(zhǎng)度更長(zhǎng),更安全的哈希加密算法+安全隨機(jī)鹽值對(duì)明文密碼進(jìn)行哈希加密
登錄場(chǎng)景下需要注意的地方就稍微多一點(diǎn),因?yàn)槊芪囊膊话踩?。攻擊者不需要指定明文,只要截獲密文一樣可以進(jìn)行登錄操作。
所以我們需要一個(gè)臨時(shí)登錄碼code,來防止攻擊者的重放攻擊。臨時(shí)登錄碼中涉及可以包含過期時(shí)間以及一些自定義的信息,然后每次用戶登錄的時(shí)候不僅要攜帶常見的登錄信息數(shù)據(jù),同時(shí)還要放上服務(wù)端頒發(fā)的臨時(shí)登錄碼。
這樣攻擊者每次截獲的登錄密文都會(huì)不一樣,及時(shí)能夠截獲有效的登錄密文數(shù)據(jù),也無法再重放登錄請(qǐng)求了。
另外的一個(gè)需要考慮的事情就是登錄保持,常見的做法是服務(wù)端會(huì)再用戶登錄成功會(huì)頒布登錄態(tài)給到用戶,一般是存儲(chǔ)在cookie中。還有一種就是JWT的方式,通過Header傳遞登錄態(tài)信息。會(huì)話的安全性也就成了我們要解決和防范的問題,如果攻擊者進(jìn)行了會(huì)話劫持,那么就可能使用用戶的會(huì)話進(jìn)行系統(tǒng)資源的訪問。
主要有幾個(gè)點(diǎn)可以進(jìn)行防范,一個(gè)是會(huì)話ID不可預(yù)測(cè),使用隨機(jī)的比如UUID等,生成會(huì)話ID。另一個(gè)是設(shè)置較短的會(huì)話超時(shí)時(shí)間,減少單個(gè)會(huì)話的訪問有效性。降低系統(tǒng)被攻擊的風(fēng)險(xiǎn),還有一個(gè)就是從HTTP協(xié)議header中對(duì)請(qǐng)求進(jìn)行更細(xì)致的判斷和規(guī)定,比如UserAgent、Refer等。或者對(duì)某些接口做接口簽名,防止攻擊者隨意偽造請(qǐng)求。
下面是我畫的登錄用例時(shí)序圖

總結(jié)
需要解決的問題:攻擊者重放攻擊、會(huì)話安全性
解決方案:臨時(shí)登錄碼、接口簽名、減小會(huì)話有效期
HTTPS原理和流程
HTTPS也是比較典型的數(shù)據(jù)傳輸安全解決方案,具體的流程可以參考這兩篇文章,主要講SSL/TLS協(xié)議。
SSL/TLS協(xié)議運(yùn)行機(jī)制的概述
文章最后
軟件系統(tǒng)的安全性保護(hù)沒那么簡(jiǎn)單,需要很多方方面面的知識(shí)和經(jīng)驗(yàn),才能做到比較安全的保護(hù)。通過這一次的總結(jié)學(xué)習(xí),大概了解了常見的加密算法的作業(yè)和實(shí)踐。以及具體場(chǎng)景下需要考慮的問題和解決方案,當(dāng)我再面對(duì)同樣的需求,和同事們討論的時(shí)候也不至于一竅不通啥也不懂啦。