目錄
一欧芽、MD5
?1莉掂、MD5是什么
?2、MD5的特點
?3千扔、MD5的問題
?4憎妙、MD5的應用場景
?5、MD5的代碼
二曲楚、SHA-1
?1厘唾、SHA-1是什么
?2、SHA-1的代碼
一龙誊、MD5
1抚垃、MD5是什么
MD5(Message Digest Algorithm 5),消息摘要算法第五版趟大。
消息摘要算法又稱為哈希算法鹤树、散列算法,輸出的消息摘要又稱為哈希值逊朽、散列值罕伯。
2、MD5的特點
- 壓縮性:MD5可以將任意長度的輸入轉化為128位長度的輸出叽讳;
- 不可逆性:MD5是不可逆的追他,我們無法通過常規(guī)方式從MD5值倒推出它的原文坟募;
- 抗修改性:對原文做一丁點兒改動,MD5值就會有巨大的變動邑狸,也就是說就算兩個MD5值非常相似懈糯,你也不能想當然地認為它們倆對應的原文也非常相似。
3推溃、MD5的問題
因為MD5是不可逆的昂利,所以MD5是安全的届腐。但是2004年铁坎,山東大學的王小云教授在美國加州舉辦的密碼學會議上宣布破解了MD5,其實并不是真正的破解犁苏,而是非常明顯地加快了反向查詢的速度硬萍,在當時計算機的計算能力下,利用她們的技術围详,可以在幾個小時內就找到一個MD5值對應的原文朴乖。因為MD5可以被暴力破解,所以MD5不再是安全的了助赞,對安全性要求較高的場合买羞,不建議直接使用MD5。
4雹食、MD5的應用場景
4.1 對密碼加密
MD5可以用來對密碼加密畜普,防止密碼被竊聽。
- 為什么要對密碼加密
比如一個用戶的用戶名為18666666666群叶,密碼為123456吃挑,那么如果不對密碼加密,客戶端在注冊或登錄的時候街立,就是明文傳輸密碼http://localhost:8080/hw/register|login?username=18666666666&password=123456
舶衬,傳輸過程中一旦請求被截獲,用戶的密碼就被泄漏了赎离;再者服務器的數(shù)據(jù)庫中也是明文存儲密碼
username | password |
---|---|
18666666666 | 123456 |
一旦數(shù)據(jù)庫泄漏逛犹,用戶的密碼就被泄漏了。
而如果我們使用了MD5對密碼加密梁剔,客戶端在注冊或登錄的時候虽画,就是密文傳輸密碼http://localhost:8080/hw/register|login?username=18666666666&password=e10adc3949ba59abbe56e057f20f883e
,傳輸過程中即便請求被截獲憾朴,用戶的密碼也不會被泄漏狸捕;再者服務器的數(shù)據(jù)庫中也是密文存儲密碼
username | password |
---|---|
18666666666 | e10adc3949ba59abbe56e057f20f883e |
就算數(shù)據(jù)庫泄漏,用戶的密碼也不會被泄漏众雷。
- 彩虹表灸拍、加鹽
攻擊者創(chuàng)建了一個叫彩虹表的東西做祝,它是一個非常龐大的數(shù)據(jù)庫,里面收集了所有常用的密碼鸡岗,以及這些密碼對應的MD5值混槐、SHA-1值等轩性,現(xiàn)在主流的彩虹表記錄數(shù)據(jù)約90萬億條,占用硬盤超過500TB揣苏。有了彩虹表,攻擊者就可以通過窮舉法反向查詢出MD5值卸察、SHA-1值等對應的原文脯厨,因此如果你的密碼很不幸被搜集在彩虹表里,就可能被破解掉坑质,這也是為什么很多場合我們輸密碼的時候,有字母數(shù)字下劃線大小寫等亂七八糟各種要求涡扼,目的就是盡量使得明文密碼的復雜度增加一些稼跳,盡量使得明文密碼及其MD5值吃沪、SHA-1值等不被收集在彩虹表里汤善。
可見直接使用MD5加密是不安全的,但是我們可以加鹽巷波。加鹽是指在密碼的任意位置插入一些指定的字符串(即鹽值salt)萎津,加鹽的目的也是為了盡量增強明文密碼的復雜度抹镊,盡量使得明文密碼及其MD5值锉屈、SHA-1值等不被收集在彩虹表里垮耳。
4.2 生成數(shù)字簽名
MD5可以用來生成數(shù)字簽名,驗證數(shù)據(jù)是否被篡改终佛。
5、MD5的代碼
//
// EncryptUtil.h
//
#import <Foundation/Foundation.h>
@interface EncryptUtil : NSObject
/**
* MD5加密铃彰,返回32位十六進制小寫密文
*
* @param plaintext 明文
*
* @return 密文
*/
+ (NSString *)md5LowercaseCiphertextFromString:(NSString *)plaintext;
/**
* MD5加密,返回32位十六進制大寫密文
*
* @param plaintext 明文
*
* @return 密文
*/
+ (NSString *)md5UppercaseCiphertextFromString:(NSString *)plaintext;
@end
//
// EncryptUtil.m
//
#import "EncryptUtil.h"
#import <CommonCrypto/CommonCrypto.h>
@implementation EncryptUtil
+ (NSString *)md5LowercaseCiphertextFromString:(NSString *)plaintext {
// 加密數(shù)組(占16個字節(jié))
unsigned char resultArray[CC_MD5_DIGEST_LENGTH];
// 加密
CC_MD5(plaintext.UTF8String, (CC_LONG)strlen(plaintext.UTF8String), resultArray);
// 密文
NSMutableString *md5Ciphertext = [NSMutableString string];
for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[md5Ciphertext appendFormat:@"%02x", resultArray[i]]; // x代表十六進制
}
return md5Ciphertext;
}
+ (NSString *)md5UppercaseCiphertextFromString:(NSString *)plaintext {
// 加密數(shù)組(占16個字節(jié))
unsigned char resultArray[CC_MD5_DIGEST_LENGTH];
// 加密
CC_MD5(plaintext.UTF8String, (CC_LONG)strlen(plaintext.UTF8String), resultArray);
// 密文
NSMutableString *md5Ciphertext = [NSMutableString string];
for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[md5Ciphertext appendFormat:@"%02X", resultArray[i]]; // X代表十六進制
}
return md5Ciphertext;
}
@end
二竹揍、SHA-1
1敬飒、SHA-1是什么
SHA(Secure Hash Algorithm)芬位,安全哈希算法,包括SHA-1昧碉、SHA-256、SHA-512等被饿。
SHA-1和MD5都是由MD4導出的,所以它們的特點锹漱、問題和應用場景基本一致。它們的區(qū)別就是SHA-1輸出的長度是160位哥牍,MD5的輸出是128位喝检,2的160次方是遠遠超過2的128次方這個數(shù)量級的,所以SHA-1相對來說要比MD5更安全一些挠说,但也可以被暴力破解。
2损俭、SHA-1的代碼
//
// EncryptUtil.h
//
#import <Foundation/Foundation.h>
@interface EncryptUtil : NSObject
/**
* SHA-1加密,返回40位十六進制小寫密文
*
* @param plaintext 明文
*
* @return 密文
*/
+ (NSString *)sha1LowercaseCiphertextFromString:(NSString *)plaintext;
/**
* SHA-1加密杆兵,返回40位十六進制大寫密文
*
* @param plaintext 明文
*
* @return 密文
*/
+ (NSString *)sha1UppercaseCiphertextFromString:(NSString *)plaintext;
@end
//
// EncryptUtil.m
//
#import "EncryptUtil.h"
#import <CommonCrypto/CommonCrypto.h>
@implementation EncryptUtil
+ (NSString *)sha1LowercaseCiphertextFromString:(NSString *)plaintext {
const char *cstr = [plaintext cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:plaintext.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString *sha1Ciphertext = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(NSInteger i = 0; i < CC_SHA1_DIGEST_LENGTH; i ++) {
[sha1Ciphertext appendFormat:@"%02x", digest[I]]; // x代表十六進制
}
return sha1Ciphertext;
}
+ (NSString *)sha1UppercaseCiphertextFromString:(NSString *)plaintext {
const char *cstr = [plaintext cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:plaintext.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString *sha1Ciphertext = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(NSInteger i = 0; i < CC_SHA1_DIGEST_LENGTH; i ++) {
[sha1Ciphertext appendFormat:@"%02X", digest[I]]; // X代表十六進制
}
return sha1Ciphertext;
}
@end