Hash (散列函數(shù))
1.Hash定義
Hash:把任意長度的輸入,通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)。
2.哈希的特點
1.同樣的輸入會有同樣的哈希值。
2.同一個哈希值可以從不同的輸入得到。
3.任意長度的輸入得到的輸出長度固定,也就是說這種算法是不可以逆的。
3.哈希的用途
- 數(shù)字簽名
- 文件比對,同一個文件的hash值是一樣的,而且Hash值是很難重復的。
- git 提交的版本對比號碼
- 原文加密,比如用戶的密碼。在客戶端和服務器直接使用加密后的密碼,這樣黑客很難得到用戶的真實輸入的密碼。
4.常用的函數(shù)
// data 需要加密的數(shù)據(jù) len 加密數(shù)據(jù)的長度 md 加密后的結(jié)果
//MD5
CC_MD5(const void *data, CC_LONG len, unsigned char *md)
// SHA1
CC_SHA1(const void *data, CC_LONG len, unsigned char *md)
// SHA256
CC_SHA256(const void *data, CC_LONG len, unsigned char *md)
5.高級版的哈希算法 - HMAC
HMAC是密鑰相關(guān)的哈希運算消息認證碼(HMAC運算利用哈希算法,以一個密鑰和一個消息為輸入,生成一個消息摘要作為輸出。
// SHA512
CC_SHA512(const void *data, CC_LONG len, unsigned char *md)
// CCHmac
/* algorithm 有:
kCCHmacAlgSHA1,
kCCHmacAlgMD5,
kCCHmacAlgSHA256,
kCCHmacAlgSHA384,
kCCHmacAlgSHA512,
kCCHmacAlgSHA224
*/
// key 加固數(shù)據(jù)
void CCHmac(
CCHmacAlgorithm algorithm, /* kCCHmacAlgSHA1, kCCHmacAlgMD5 */
const void *key,
size_t keyLength, /* length of key in bytes */
const void *data,
size_t dataLength, /* length of data in bytes */
}
6.終端生成Hash 值命令, 我們義字符串 “hello world” 為例
md5 -s "hello world" //MD5
echo -n "hello world"" | openssl sha -sha1 //SHA1
echo -n "hello world"" | openssl sha -sha256 //SHA256
echo -n "hello world"" | openssl sha -sha512 //SHA512
echo -n "hello world"" | openssl dgst -md5 -hmac "key" //HMAC + MD5
echo -n "hello world"" | openssl sha -sha1 -hmac "key" /HMAC + SHA1
echo -n "hello world"" | openssl sha -sha256 -hmac "key" /HMAC + SHA256
echo -n "hello world"" | openssl sha -sha512 -hmac "key" /HMAC + SHA512
Hash 破解與防范
破解原理
- 通過窮舉字符組合的方式,創(chuàng)建了明文密文對應查詢數(shù)據(jù)庫。 這種破解的一般是密碼,這種簡單的字符串
- 獲得簽名的規(guī)則和加鹽值,進行重簽名,然后就可以更改參數(shù)的值
防范
- 對于密碼的轉(zhuǎn)化,可以使用更難窮舉的HMAC
- 對于重簽名,加鹽的參數(shù)不放在客戶端【客戶端可逆向獲取】
- 對于網(wǎng)絡傳輸加鹽值可以截取的問題,可以將這個設置一個時效性。
- 參數(shù)不要采用明文,可以使用一定的加密方式
對稱加密
常見的對稱加密方式
DES 3DES AES "高級"加密標準
ECB 電子代碼本,每個塊都是獨立加密的
CBC 密碼塊鏈:使用一個密鑰和一個初始化向量 (IV)對數(shù)據(jù)執(zhí)行加密轉(zhuǎn)換,可以有效地保證密文的完整性。
重要的函數(shù)
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)
enum {
kCCModeECB = 1,
kCCModeCBC = 2,
kCCModeCFB = 3,
kCCModeCTR = 4,
kCCModeF8 = 5, // Unimplemented for now (not included)
kCCModeLRW = 6, // Unimplemented for now (not included)
kCCModeOFB = 7,
kCCModeXTS = 8,
kCCModeRC4 = 9,
kCCModeCFB8 = 10,
};
參數(shù)說明
1.CCOperation: kCCEncrypt:加密, kCCDecrypt:解密
2.alg 加密解密方式
2.1 kCCAlgorithmAES128 = 0
2.2 kCCAlgorithmAES = 0
2.3 kCCAlgorithmDES,
2.4 kCCAlgorithm3DES,
2.5 kCCAlgorithmCAST,
2.6 kCCAlgorithmRC4,
2.7 kCCAlgorithmRC2,
2.8 kCCAlgorithmBlowfish
3.options 加密選項 kCCOptionPKCS7Padding | kCCOptionECBMode 如果用了iv 就有 kCCOptionECBMode
4.key 加密解密的密鑰
5.keyLength 加密的長度, 根據(jù)alg 類型取對應的長度
6.iv 初始化向量
7.dataIn 加密數(shù)據(jù)
8.dataInLength 加密數(shù)據(jù)的長度
9.dataOut 加密解密后的數(shù)據(jù)
10.dataOutAvailable dataOut的長度
11.dataOutMoved 數(shù)據(jù)最后的長度
非對稱加密
重要函數(shù)
SecKeyDecrypt(
SecKeyRef key, /* Private key */
SecPadding padding, /* kSecPaddingNone,kSecPaddingPKCS1, kSecPaddingOAEP */
const uint8_t *cipherText,
size_t cipherTextLen,/* length of cipherText */
uint8_t *plainText,
size_t *plainTextLen)
SecKeyDecrypt 使用公鑰加密
SecKeyRef 公鑰
SecPadding
cipherText 加密的數(shù)據(jù)
cipherTextLen 加密數(shù)據(jù)的長度
plainText 結(jié)果數(shù)據(jù)
plainTextLen 數(shù)據(jù)結(jié)果的長度
SecKeyDecrypt 使用私鑰解密
SecKeyDecrypt(
SecKeyRef key, /* Private key */
SecPadding padding,/* kSecPaddingNone, kSecPaddingPKCS1,kSecPaddingOAEP */
const uint8_t *cipherText,
size_t cipherTextLen,/* length of cipherText */
uint8_t *plainText,
size_t *plainTextLen)