Hash一般譯為“散列”,也有直接音譯為“哈希”,就是把任意長度的輸入通過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,所以不可能從散列值來確定唯一的輸入值,簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
Hash的特點
- 算法是公開的
- 對相同數據運算得到的結果是一樣的
- 對不同數據運算,如MD5得到的結果默認是128位,32個字符(16進制標識)
- 不可逆運算
-
信息摘要,信息“指紋”,是用來做數據識別的
目前常見的散列算法
Hash的用途
- 用戶密碼加密:將密碼進行加密后存儲在服務器,以防止賬號信息泄漏。
- 保護資料\版權:散列值可用于唯一地識別機密信息。
- 確保傳遞真實的信息:消息或數據的接受者確認消息是否被篡改的性質叫數據的真實性,也稱為完整性。發信人通過將原消息和散列值一起發送,可以保證真實性。如數字簽名
- 搜索引擎:對搜索內容進行分詞后使用hash計算出結果的和,然后匹配出搜索結果。
- 語音識別:如分析正在播放的音樂,并將它于存儲在數據庫中的已知的散列值進行比較。用戶就能夠收到被識別的音樂的曲名。
在實際應用中,不能直接使用MD5,如果直接使用的話,很可能會被破解,如網站cmd5通過窮舉字符組合進行反向查詢。所以我們在應用的時候可以使用一些手段,如HMAC
方案,通過加key、時間戳等手段進行二次hash運算。
對稱密鑰加密
又稱為對稱加密、私鑰加密、共享密鑰加密。這類算法在加密和解密時使用相同的密鑰,或是使用兩個可以簡單地相互推算的密鑰。常見的對稱加密算法有AES("高級加密標準")、ChaCha20、3DES、Salsa20、DES("數據加密標準")、Blowfish、IDEA( "國際資料加密算法")、RC5、RC6、Camellia
。對稱加密的速度比公鑰加密快很多,在很多場合都需要對稱加密。
對稱加密有兩種不同的應用模式:
- ECB(Electronic Code Book):電子密碼本模式,每一塊數據獨立加密,它是最基本的加密模式,相同的明文將永遠加密成相同的密文。它容易受到密碼本重放攻擊,一般情況下很少用。
- CBC(Cipher Block Chaining):密碼分組鏈接模式,使用一個密鑰和一個初始化向量[IV]對數據執行加密。
明文被加密前要與前面的密文進行異或運算后再密碼,因此只要選擇不同的初始向量,相同的密文加密后會形成不同的密文,這是目前應用最廣泛的模式。第一塊數據都與前面是關聯的,因此CBC可以有效的保證密文的完整性,如果數據塊傳遞過程中丟失,那么其后面的數據將無法正常解密。
使用openssl加解密
-
加密:
- AES(ECB)加密“hello”字符串
$ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
- AES(CBC)加密“hello”字符串
$ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
- AES(ECB)加密“hello”字符串
-
解密:
- AES(ECB)解密
echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt –d
- AES(CBC)解密
echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt –d
- AES(ECB)解密
OC代碼使用
引入頭文件#import <CommonCrypto/CommonCrypto.h>
,加解密都是使用同一個方法
/*參數說明
1、kCCEncrypt 加密/kCCDecrypt 解密
2、加密算法。
3、加密選項:ECB/CBC,iv存在使用kCCOptionPKCS7Padding,不存在使用kCCOptionPKCS7Padding | kCCOptionECBMode
4、加密的密鑰
5、密鑰的長度
6、iv 初始化向量
7、加密的數據
8、加密的數據長度
9、密文的內存地址
10、密文緩沖區的大小
11、加密結果大小
*/
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
API_AVAILABLE(macos(10.4), ios(2.0));