HSAH
Hash,一般翻譯做“散列”,也有直接音譯為“哈?!钡?,就是把任意長度的輸入通過散列算法變換成固定長度的輸出,該輸出就是散列值。
簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)
Hash的特點
?算法是公開的
?對相同數(shù)據(jù)運算,得到的結果是一樣的
?對不同數(shù)據(jù)運算,如MD5得到的結果默認是128位,32個字符(16進制標識)。
?這玩意沒法逆運算(32個字符所能表達的數(shù)據(jù)是不定長的,散列碰撞)
?信息摘要,信息“指紋”,是用來做數(shù)據(jù)識別的。
加密方式
非對稱加密 : RSA
對稱加密 : DES 、 3DES 、AES
HASH: MD5 、 SHA1 / SHA256
用途
?用戶密碼的加密
?搜索引擎
?版權 (相似的文件的hash值不同,可視為正版盜版的一個判定依據(jù),同個文件改文件名或類型或copy后,hash值并不發(fā)生改變,只有改變二進制排列才會產(chǎn)生變化)
?數(shù)字簽名
HASH加密方式:
1.加鹽 壞處:鹽一旦泄露 就不安全了,鹽是寫死的。
2.HMAC加密方案
使用一個密鑰加密,并且做了兩次散列,?在實際開發(fā)中,密鑰來自于服務器
- (NSString*)hmacMD5StringWithKey:(NSString*)key {}
例如用戶注冊登錄:
注冊時先把賬號發(fā)給服務器匹配賬號是否可以使用,可以使用后隨機生成key密鑰,然后將密鑰發(fā)給客戶端,客戶端拿到key值后再進行HMAC加密,加密之后得到的HASH值發(fā)給服務器。
如果換了設備登錄的話,就找服務器要對應賬號的key,輸入密碼用key進行HMAC加密,然后將加密的結果發(fā)給服務器驗證,驗證成功后登錄成功,將key保存在本地,沒有登錄成功將key刪除。
加一步:如果設備開啟了授權設備鎖,那么向服務器索要key的時候會向已授權設備發(fā)送驗證, 授權設備允許后將key給與新的設備。
漏洞:不需要獲得用戶的真實密碼,直接將加密后的md5值發(fā)送給服務器,一樣可以登錄。
HMAC

升級后HMAC加密:
在生成的 HMAC哈希值 的后面添加一個當前時間的字符串(可能是當前的年月日時分),在求一次md5,然后發(fā)送給服務器,服務器驗證?HMAC哈希值 加上當前的時間的字符串(有時加上上一分鐘的字符創(chuàng))進行md5運算,這樣這個值的有效期在1分鐘到1分鐘59秒之間。
這樣的好處是每次加密的結果都不一樣,這個時間戳是服務器給的。
密碼加密方式
?直接使用MD5
?MD5加鹽
?HMAC加密方案
?添點東西
源代碼

?#define CC_MD5_DIGEST_LENGTH? ? 16? ? ? ? ? /* digest length in bytes */ 16個字節(jié),16*8 = 128位的二進制
? ? constchar*str =self.UTF8String;//加密數(shù)據(jù)的指針
? ? uint8_t buffer[CC_MD5_DIGEST_LENGTH];//加密數(shù)據(jù)的長度,
? ? CC_MD5(str, (CC_LONG)strlen(str), buffer);、
? ? return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];

數(shù)字簽名
將原始數(shù)據(jù)的hash值用RSA進行加密,發(fā)給服務器的將是原始數(shù)據(jù)和用RSA加密后的hash值,然后服務器解密,對比原始數(shù)據(jù)進行相同算法的hash值,如果匹配說明數(shù)據(jù)沒有被修改過,這就叫做數(shù)字簽名。
代碼簽名
對稱加密
對稱加密方式:明文通過密鑰加密得到密文。密文通過密鑰解密得到明文。
常見算法
?DES? ? 數(shù)據(jù)加密標準(用得少,因為強度不夠)
?3DES? 使用3個密鑰,對相同的數(shù)據(jù)執(zhí)行3次加密,強度增強
?AES? 高級密碼標準。(鑰匙串訪問)
應用模式
?ECB(Electronic Code Book):電子密碼本模式。每一塊數(shù)據(jù),獨立加密。
?最基本的加密模式,也就是通常理解的加密,相同的明文將永遠加密成相同的密文,無初始向量,容易受到密碼本重放攻擊,一般情況下很少用。
?CBC(Cipher Block Chaining):密碼分組鏈接模式。使用一個密鑰和一個初始化向量[IV]對數(shù)據(jù)執(zhí)行加密。加密解密都會依賴前一塊數(shù)據(jù)。(防竊聽的技術)
?明文被加密前要與前面的密文進行異或運算后再加密,因此只要選擇不同的初始向量,相同的密文加密后會形成不同的密文,這是目前應用最廣泛的模式。CBC加密后的密文是上下文相關的,但明文的錯誤不會傳遞到后續(xù)分組,但如果一個分組丟失,后面的分組將全部作廢(同步錯誤)。
?CBC可以有效的保證密文的完整性,如果一個數(shù)據(jù)塊在傳遞是丟失或改變,后面的數(shù)據(jù)將無法正常解密。
$ openssl enc -des-ecb -k -616263 -nosalt -in message.txt -out msg1.bin? (用ecb進行加密)
$ openssl enc -des-cbc -iv 0102030405060708 -k 616263 -nosalt -in message.txt -out msg4.bin? (用cbc進行加密)
xxd msg1.bin? (查看)
- k 616263 傳遞的就是二進制 (abc)
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 -K 616263 -nosalt -iv 0102030405060708 | base64
?解密:
?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 -K 616263 -iv 0102030405060708 -nosalt -d
代碼
需要導入 EncryptionTools.h


iv (初始化向量)有值就是cbc, 無值就是ecb,返回的結果是個base的字符串
加密解密都是它 -- CCCrypt? 參數(shù)說明
? ? CCCrypt(<#CCOperation op#>, <#CCAlgorithm alg#>, <#CCOptions options#>, <#const void *key#>, <#size_t keyLength#>, <#const void *iv#>, <#const void *dataIn#>, <#size_t dataInLength#>, <#void *dataOut#>, <#size_t dataOutAvailable#>, <#size_t *dataOutMoved#>)
?? ? 1、kCCEncrypt 加密/kCCDecrypt 解密
?? ? 2、加密算法。
?? ? 3、加密選項:ECB/CBC
?? ? 4、加密的密鑰
?? ? 5、密鑰的長度
?? ? 6、iv 初始化向量
?? ? 7、加密的數(shù)據(jù)
?? ? 8、加密的數(shù)據(jù)長度
?? ? 9、密文的內(nèi)存地址
?? ? 10、密文緩沖區(qū)的大小
?? ? 11、加密結果大小
弊端:可以 symbolic 斷點斷住?CCCrypt 函數(shù)
函數(shù)調用的參數(shù)存在cpu的寄存器中
register read x6? ?(x6 是因為第7個參數(shù)是加密的數(shù)據(jù))
p (char *)0x00000001c000ec20? ? (顯示加密的數(shù)據(jù))