一、散列(哈希)
1.簡介
散列函數(shù),又稱散列算法、哈希函數(shù),是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。散列函數(shù)把消息或數(shù)據(jù)壓縮成摘要,使得數(shù)據(jù)量變小,將數(shù)據(jù)的格式固定下來。該函數(shù)將數(shù)據(jù)打亂混合,重新創(chuàng)建一個(gè)叫做散列值(hash values,hash codes,hash sums,或hashes)的指紋。散列值通常用一個(gè)短的隨機(jī)字母和數(shù)字組成的字符串來代表。
將數(shù)據(jù)(如一段文字)運(yùn)算變?yōu)榱硪还潭ㄩL度值,是散列算法的基礎(chǔ)原理。
2.特點(diǎn)
- 對相同數(shù)據(jù)運(yùn)算,結(jié)果相同
- 對不同數(shù)據(jù)運(yùn)算,結(jié)果長度相同
- 運(yùn)算單向不可逆
3.常用算法
-
MD5
MD5消息摘要算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個(gè)128位(16字節(jié),32個(gè)字符)的散列值(hash value),用于確保信息傳輸完整一致。 -
SHA家族
安全散列算法(英語:Secure Hash Algorithm,縮寫為SHA)是一個(gè)密碼散列函數(shù)家族,是FIPS所認(rèn)證的安全散列算法。
MD5使用比較頻繁,但是如果只是簡單使用MD5安全性較低,目前已有網(wǎng)站提供部分MD5破解,如https://www.cmd5.com。為了增加安全性,使用MD5時(shí)一般會(huì)在加密數(shù)據(jù)后加上某個(gè)隨機(jī)值(就是所謂的加鹽),然后再進(jìn)行MD5運(yùn)算。
HMAC,全稱為“Hash Message Authentication Code”,中文名“散列消息鑒別碼”,主要是利用哈希算法,以一個(gè)密鑰和一個(gè)消息為輸入,生成一個(gè)消息摘要作為輸出。秘鑰就是我們上述所說的‘鹽’,使用HMAC會(huì)加大安全性,同時(shí)HMAC對所有散列算法都有效。
4.實(shí)際應(yīng)用
哈希算法用途很多,比如用戶密碼加密、文件校驗(yàn)、數(shù)字簽名和數(shù)據(jù)檢索。
用戶密碼加密
這里提供一個(gè)用戶密碼加密的方案:采用HMAC+MD5的方式進(jìn)行加密,每個(gè)用戶對應(yīng)一個(gè)KEY作為HMAC的秘鑰,HMAC運(yùn)算結(jié)果再加上服務(wù)器返回的時(shí)間戳進(jìn)行MD5,最終得到的值在網(wǎng)絡(luò)上進(jìn)行傳輸。為了進(jìn)一步提高安全性KEY可以每過一段時(shí)間更換一次。

獲取KEY的時(shí)機(jī):
- 注冊時(shí)
- 登陸時(shí)本地沒有KEY
- 登陸時(shí)本地有KEY,但是檢測該賬號(hào)更換了設(shè)備
服務(wù)器和客戶端加密數(shù)據(jù)對比:
- 首先服務(wù)器存儲(chǔ)的是HMAC(密碼+KEY) = password,返回客戶端的時(shí)間戳是timeInterval
- 服務(wù)器會(huì)計(jì)算2個(gè)值:MD5(password + timeInterval) = password_s1;MD5(password + (timeInterval - 60s)) = password_s2
- 客戶端請求的密碼數(shù)據(jù)是MD5( HMAC(密碼 + KEY) + 時(shí)間戳) = password_app
- 服務(wù)器會(huì)對比password_app是否是password_s1和password_s2中的一個(gè)值,如果匹配到則密碼校驗(yàn)成功
文件校驗(yàn)
MD5和SHA1都具有高度的離散性,哪怕是只修改一個(gè)字節(jié)值都會(huì)導(dǎo)致MD5或SHA1值“巨大”變化,從實(shí)踐角度,不同信息具有相同MD5或SHA1碼 的可能性非常低,通常認(rèn)為是不可能的。
MD5 Hash算法的"數(shù)字指紋"特性,使它成為目前應(yīng)用最廣泛的一種文件完整性校驗(yàn)和(Checksum)算法。
注:秒傳就是利用文件校驗(yàn)原理,哈希值相同代表改文件已經(jīng)存在服務(wù)器,造成一種秒傳的假象。
數(shù)字簽名
由于哈希算法的唯一性,可以利用數(shù)據(jù)的哈希值判斷數(shù)據(jù)是否被篡改,以此實(shí)現(xiàn)數(shù)字簽名。通常傳遞給服務(wù)器的哈希值是經(jīng)過RSA加密的。
數(shù)據(jù)檢索
對搜索關(guān)鍵字進(jìn)行哈希,通過哈希值匹配文件的關(guān)鍵字哈希值,以此實(shí)現(xiàn)檢索。
二、對稱加密
1.簡介
對稱密鑰加密(英語:Symmetric-key algorithm)又稱為對稱加密、私鑰加密、共享密鑰加密,是密碼學(xué)中的一類加密算法。這類算法在加密和解密時(shí)使用相同的密鑰,或是使用兩個(gè)可以簡單地相互推算的密鑰。
2.特點(diǎn)
- 計(jì)算量小
- 加密速度快、機(jī)密效率高
- 加密和解密使用相同秘鑰,安全隱患大
3.常用算法
-
DES
數(shù)據(jù)加密標(biāo)準(zhǔn)(英語:Data Encryption Standard,縮寫為 DES)是一種對稱密鑰加密算法。
DES現(xiàn)在已經(jīng)不是一種安全的加密方法,主要因?yàn)樗褂玫?6位密鑰過短。 -
3DES
三重?cái)?shù)據(jù)加密算法(英語:Triple Data Encryption Algorithm,縮寫為TDEA,Triple DEA),或稱3DES(Triple DES),是一種對稱密鑰加密塊密碼,相當(dāng)于是對每個(gè)數(shù)據(jù)塊應(yīng)用三次數(shù)據(jù)加密標(biāo)準(zhǔn)(DES)算法。
由于計(jì)算機(jī)運(yùn)算能力的增強(qiáng),原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設(shè)計(jì)用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設(shè)計(jì)一種全新的塊密碼算法。 -
AES
高級(jí)加密標(biāo)準(zhǔn)(英語:Advanced Encryption Standard,縮寫:AES),是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。
密碼學(xué)中,分組(block)密碼的工作模式(mode of operation)允許使用同一個(gè)分組密碼密鑰對多于一塊的數(shù)據(jù)進(jìn)行加密,并保證其安全性。分組密碼自身只能加密長度等于密碼分組長度的單塊數(shù)據(jù),若要加密變長數(shù)據(jù),則數(shù)據(jù)必須先被劃分為一些單獨(dú)的密碼塊。通常而言,最后一塊數(shù)據(jù)也需要使用合適填充方式將數(shù)據(jù)擴(kuò)展到匹配密碼塊大小的長度。
工作模式通常應(yīng)用于對稱加密,這里主要介紹一下ECB和CBC兩種工作模式。
電子密碼本(ECB)
最簡單的加密模式即為電子密碼本(Electronic codebook,ECB)模式。需要加密的消息按照塊密碼的塊大小被分為數(shù)個(gè)塊,并對每個(gè)塊進(jìn)行獨(dú)立加密。


ECB模式的缺點(diǎn)在于同樣的明文塊會(huì)被加密成相同的密文塊;因此,它不能很好的隱藏?cái)?shù)據(jù)模式。
下面的例子顯示了ECB在密文中顯示明文的模式的程度:該圖像的一個(gè)位圖版本(左圖)通過ECB模式可能會(huì)被加密成中圖,而非ECB模式通常會(huì)將其加密成右圖。

密碼塊鏈接(CBC)
IBM發(fā)明了密碼分組鏈接(CBC,Cipher-block chaining)模式。在CBC模式中,每個(gè)明文塊先與前一個(gè)密文塊進(jìn)行異或后,再進(jìn)行加密。在這種方法中,每個(gè)密文塊都依賴于它前面的所有明文塊。同時(shí),為了保證每條消息的唯一性,在第一個(gè)塊中需要使用初始化向量。


CBC是最為常用的工作模式。它的主要缺點(diǎn)在于加密過程是串行的,無法被并行化,而且消息必須被填充到塊大小的整數(shù)倍。
CBC模式在加密時(shí),明文中的微小改變會(huì)導(dǎo)致其后的全部密文塊發(fā)生改變,而在解密時(shí),從兩個(gè)鄰接的密文塊中即可得到一個(gè)明文塊。因此,解密過程可以被并行化,而解密時(shí),密文中一位的改變只會(huì)導(dǎo)致其對應(yīng)的明文塊完全改變和下一個(gè)明文塊中對應(yīng)位發(fā)生改變,不會(huì)影響到其它明文的內(nèi)容。
三、非對稱加密
公開密鑰加密(英語:Public-key cryptography),也稱為非對稱加密(英語:asymmetric cryptography),是密碼學(xué)的一種算法,它需要兩個(gè)密鑰,一個(gè)是公開密鑰,另一個(gè)是私有密鑰;一個(gè)用作加密的時(shí)候,另一個(gè)則用作解密。使用其中一個(gè)密鑰把明文加密后所得的密文,只能用相對應(yīng)的另一個(gè)密鑰才能解密得到原本的明文;由于加密和解密需要兩個(gè)不同的密鑰,故被稱為非對稱加密。
常見的公鑰加密算法有:RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫爾曼密鑰交換協(xié)議中的公鑰加密算法、橢圓曲線加密算法(英語:Elliptic Curve Cryptography, ECC)。使用最廣泛的是RSA算法(由發(fā)明者Rivest、Shmir和Adleman姓氏首字母縮寫而來)是著名的公開秘鑰加密算法,ElGamal是另一種常用的非對稱加密算法。
1.RSA介紹
RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業(yè)中RSA被廣泛使用。RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當(dāng)時(shí)他們?nèi)硕荚?a target="_blank" rel="nofollow">麻省理工學(xué)院工作。RSA就是他們?nèi)诵帐祥_頭字母拼在一起組成的。
2.原理公式

m是明文,c是密文
e和n構(gòu)成公鑰
d和n構(gòu)成私鑰
3.RSA安全性
對極大整數(shù)做因數(shù)分解的難度決定了RSA算法的可靠性。換言之,對一極大整數(shù)做因數(shù)分解愈困難,RSA算法愈可靠。假如有人找到一種快速因數(shù)分解的算法的話,那么用RSA加密的信息的可靠性就肯定會(huì)極度下降。但找到這樣的算法的可能性是非常小的。今天只有短的RSA鑰匙才可能被強(qiáng)力方式解破。到目前為止,世界上還沒有任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息實(shí)際上是不能被解破的。
4.RSA特點(diǎn)
相對于DES和其他對稱算法,RSA要慢得多。一般RSA加密小量的數(shù)據(jù)
5.加密解密流程

- 如果使用公鑰加密,就要使用私鑰進(jìn)行解密
- 如果使用私鑰加密,就要使用公鑰進(jìn)行解密
實(shí)際使用中由于RSA的特點(diǎn),一般是配合AES一起使用。
四、命令行加密解密指令
- MD5
//計(jì)算MD5散列結(jié)果
md5 -s "string"
//計(jì)算SHA1散列結(jié)果
echo -n "string" | openssl sha -sha1
//計(jì)算SHA256散列結(jié)果
echo -n "string" | openssl sha -sha256
//計(jì)算SHA 512散列結(jié)果
echo -n "string" | openssl sha -sha512
//計(jì)算HMAC MD5散列結(jié)果
echo -n "string" | openssl dgst -md5 -hmac "key"
//計(jì)算HMAC SHA1散列結(jié)果
echo -n "string" | openssl sha -sha1 -hmac "key"
//計(jì)算HMAC SHA256散列結(jié)果
echo -n "string" | openssl sha -sha256 -hmac "key"
//計(jì)算HMAC SHA512散列結(jié)果
echo -n "string" | openssl sha -sha512 -hmac "key"
//計(jì)算文件的SHA1散列結(jié)果
openssl sha -sha1 file.dat
//計(jì)算文件的SHA256散列結(jié)果
openssl sha -sha256 file.dat
//計(jì)算文件的SHA512散列結(jié)果
openssl sha -sha512 file.dat
- DES、AES
//加密過程是先加密,再base64編碼
//解密過程是先base64解碼,再解密
//DES(ECB)加密
echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
//DES(ECB)解密
echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
//DES(CBC)加密
echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
//DES(CBC)解密
echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
//AES(ECB)加密
echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
//AES(ECB)解密
echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
//AES(CBC)加密
echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
//AES(CBC)解密
echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
- RSA
//加密解密
//生成私鑰,1024為秘鑰長度,為了安全性目前推薦長度至少為2048位。
openssl genrsa -out private.pem 1024
//從私鑰中提取公鑰
openssl rsa -in private.pem -pubout -out public.pem
//利用公鑰進(jìn)行加密
openssl rsautl -encrypt -in plaintext.txt -inkey public.pem -pubin -out ciphertext.txt
//利用私鑰對公鑰加密的內(nèi)容進(jìn)行解密
openssl rsautl -decrypt -in ciphertext.txt -inkey private.pem -out dec.txt
//利用私鑰進(jìn)行加密:簽名
openssl rsautl -sign -in plaintext.txt -inkey private.pem -out ciphertext.txt
//利用公鑰對私鑰加密的內(nèi)容進(jìn)行解密
openssl rsautl -verify -in ciphertext.txt -inkey public.pem -pubin -out plaintext.txt
//證書生成
//生成秘鑰
openssl genrsa -out private.pem 1024
//通過秘鑰生成請求文件,這里會(huì)要求輸入一些信息
openssl req -new -key private.pem -out rsacert.csr
//生成證書,但是程序無法直接使用:3650是證書有效時(shí)長
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
//提取公鑰文件
openssl x509 -outform der -in rsacert.crt -out rsacert.der
//提取私鑰文件
openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt