前段時間開發中用到了加密,就趁這個機會查閱了一些相關的資料,對解密加深了一些印象,以下是我的一些總結。
消息摘要算法、對稱加密算法、非對稱加密算法
首先來了解當前的幾種主流的加密方式,這幾種加密方式有各自不同的特點,對應著數據安全的不同需求,通過靈活使用這幾種加密方式能大大提高數據的安全性。
消息摘要算法
數據摘要算法也被稱為哈希(Hash)算法、散列算法。摘要算法通過對所有數據提取指紋信息以實現數據簽名,數據完整性校驗等功能由于其不可逆性,有時候會被用做敏感信息的加密。消息摘要算法的特點是將需要加密的數據進行一系列的處理最終輸出一個128的密文,一般這個密文以32個16進制的字符存儲。常見的摘要算法有CRC系列,MD系列,SHA系列以及以及PRIPEMD、PANAMA、TIGER等。
在以上的摘要算法中,MD5是比較常用的。在iOS的開發中,目前我使用到MD5的兩個場景,一個是將用戶的密碼直接MD5加密,傳輸和存儲都使用這個MD5值,保證用戶的密碼不會泄露。再一種是后臺和客戶端通信時,通過對指定的數據進行MD5加密進行身份驗證。使用MD5做以上兩種情況的加密主要是因為MD5具有以下特性:
1、壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
2、容易計算:從原數據計算出MD5值很容易。
3、抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所得到的MD5值都有很大區別。
4、強抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。
根據MD5的特點,MD5一般用于一致性驗證,數字簽名,安全訪問限制,安全訪問認證。一般的開發平臺中都會集成MD5加密,在iOS的開發中,導入CommonCrypto/CommonDigest.h頭文件即可進行MD5加密的操作,具體代碼如下:
- (NSString *)getMd5_32Bit
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[result appendFormat:@"%02x", digest[i]];
return result;
}
對稱加密算法
對稱加密(也叫私鑰加密)指加密和解密使用相同密鑰的加密算法。有時又叫傳統密碼算法,就是加密密鑰能夠從解密密鑰中推算出來,同時解密密鑰也可以從加密密鑰中推算出來。而在大多數的對稱算法中,加密密鑰和解密密鑰是相同的,所以也稱這種加密算法為秘密密鑰算法或單密鑰算法。它要求發送方和接收方在安全通信之前,商定一個密鑰。對稱算法的安全性依賴于密鑰,泄漏密鑰就意味著任何人都可以對他們發送或接收的消息解密,所以密鑰的保密性對通信的安全性至關重要。
對稱加密算法的特點是算法公開、計算量小、加密速度快、加密效率高。不足之處是,交易雙方都使用同樣鑰匙,安全性得不到保證。此外,每對用戶每次使用對稱加密算法時,都需要使用其他人不知道的惟一鑰匙,這會使得發收信雙方所擁有的鑰匙數量呈幾何級數增長,密鑰管理成為用戶的負擔。常見的對稱加密算法有:DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法以及正在普及的AES算法。
在以上對稱算法中使用較多的DES正在被安全性更高的AES算法所替代,一般的開發平臺會集成AES加密,不過AES加解密的代碼較復雜,一般使用第三方工具類進行加解密,這里就不進行代碼展示了。
在使用AES進行加解密時,可能會遇到客戶端與后臺不能正常加解密的情況,比如客戶端對數據加密之后,可以成功解密,但是將加密過后的數據傳輸到后臺之后,就不能正常解密了。產生這種情況的原因是因為在加解密時不同平臺的配置不同,所以需要注意將以下的設置在各個平臺設置一致:
1、模式 模式有ECB/CBC等,iOS默認的是CBC;
2、Padding iOS默認的是PKCS7 等價于PKCS5;
3、初始向量 iv(下圖中的NULL) iOS默認是00000000000;
4、keySize 有 128/192/256等。
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
非對稱加密算法
非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。非對稱加密的公鑰和私鑰都可以進行加解密,也就是說,公鑰可以用來加密,此時只有對應的私鑰能夠對密文進行解密;私鑰也可以進行加密,此時只有對應的公鑰可以對密文進行解密。
優點:非對稱加密與對稱加密相比,其安全性更好:對稱加密的通信雙方使用相同的秘鑰,如果一方的秘鑰遭泄露,那么整個通信就會被破解。而非對稱加密使用一對秘鑰,一個用來加密,一個用來解密,而且公鑰是公開的,秘鑰是自己保存的,不需要像對稱加密那樣在通信之前要先同步秘鑰;
缺點:非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少量數據進行加密。
在非對稱加密算法中,RSA是比較常用的一個。RSA算法基于一個數論事實:將兩個大質數相乘后很難通過結果推算出原來的兩個質數,所有可以將乘積公開作為公開密鑰。需要注意的是,各個平臺需要的密鑰的編碼格式是不一樣的,在生成密鑰的時候,應該注意這一點。其中:
Java和Andriod:私鑰—PKCS8編碼、公鑰—Base64編碼;
iOS 和PHP :私鑰—Base64編碼、公鑰—Base64編碼;
此外,iOS可以使用p12格式和der格式的數字證書來進行加解密。
以下是生成各種編碼格式密鑰的openssl語句(Mac自帶openssl,在終端執行即可,Windows系統的電腦可以下載openssl生成RSA密鑰和數字證書),如有額外的需求,可以查閱資料進行編碼格式轉換:
1、生成ASCLL(Base64)編碼的私鑰
genrsa -out atrsa_private_key.pem 1024
2、生成ASCLL(Base64)編碼的公鑰
rsa -in atrsa_private_key.pem -pubout -out atrsa_public_key.pem
3、對私鑰進行PKCS#8編碼
pkcs8 -topk8 -in atrsa_private_key.pem -out pkcs8_atrsa_private_key.pem -nocrypt
4、創建證書請求
req -new -out atrsacert.csr -key atrsa_private_key.pem
5、生成證書并且簽名
x509 -req -days 3650 -in atrsacert.csr -signkey atrsa_private_key.pem -out atrsacert.crt
6、轉換格式,將PEM 格式文件轉換成 DER 格式
x509 -outform der -in atrsacert.crt -out atrsacert.der
7、導出P12文件
pkcs12 -export -out atrsa_private_key.p12 -inkey atrsa_private_key.pem -in atrsacert.crt
</code></pre>
在生成密鑰之后,按平臺需求分配對應編碼格式的密鑰即可。RSA的加解密一般也集成在各個平臺中,需要的話可以自己封裝一個關于RSA加解密的工具類,也可以使用第三方的工具類,這個視情況而定。
總結
以上簡單介紹了消息摘要算法、對稱加密算法、非對稱加密算法。數據摘要算法不可逆主要用于驗證,對稱算法和非對稱算法可逆,但因他們各自的特性也有不同的用途,具體在什么場景應用這些算法,會在下一篇文章介紹。