介紹MD5加密算法基本情況MD5的全稱是Message-Digest Algorithm 5,在90年代初由MIT的計算機科學實驗室和RSA Data Security Inc發(fā)明,經(jīng)MD2、MD3和MD4發(fā)展而來。
金堂縣網(wǎng)站建設公司成都創(chuàng)新互聯(lián)公司,金堂縣網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為金堂縣上千多家提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設要多少錢,請找那個售后服務好的金堂縣做網(wǎng)站的公司定做!
Message-Digest泛指字節(jié)串(Message)的Hash變換,就是把一個任意長度的字節(jié)串變換成一定長的大整數(shù)。請注意我使用了"字節(jié)串"而不是"字符串"這個詞,是因為這種變換只與字節(jié)的值有關,與字符集或編碼方式無關。
MD5將任意長度的"字節(jié)串"變換成一個128bit的大整數(shù),并且它是一個不可逆的字符串變換算法,換句話說就是,即使你看到源程序和算法描述,也無法將一個MD5的值變換回原始的字符串,從數(shù)學原理上說,是因為原始的字符串有無窮多個,這有點象不存在反函數(shù)的數(shù)學函數(shù)。
MD5的典型應用是對一段Message(字節(jié)串)產(chǎn)生fingerprint(指紋),以防止被"篡改"。舉個例子,你將一段話寫在一個叫readme.txt文件中,并對這個readme.txt產(chǎn)生一個MD5的值并記錄在案,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內(nèi)容,你對這個文件重新計算MD5時就會發(fā)現(xiàn)。如果再有一個第三方的認證機構(gòu),用MD5還可以防止文件作者的"抵賴",這就是所謂的數(shù)字簽名應用。
MD5還廣泛用于加密和解密技術上,在很多操作系統(tǒng)中,用戶的密碼是以MD5值(或類似的其它算法)的方式保存的,用戶Login的時候,系統(tǒng)是把用戶輸入的密碼計算成MD5值,然后再去和系統(tǒng)中保存的MD5值進行比較,而系統(tǒng)并不"知道"用戶的密碼是什么。
一些黑客破獲這種密碼的方法是一種被稱為"跑字典"的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字符串表,另一種是用排列組合方法生成的,先用MD5程序計算出這些字典項的MD5值,然后再用目標的MD5值在這個字典中檢索。
即使假設密碼的最大長度為8,同時密碼只能是字母和數(shù)字,共26+26+10=62個字符,排列組合出的字典的項數(shù)則是P(62,1)+P(62,2)....+P(62,8),那也已經(jīng)是一個很天文的數(shù)字了,存儲這個字典就需要TB級的磁盤組,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼MD5值的情況下才可以。
在很多電子商務和社區(qū)應用中,管理用戶的Account是一種最常用的基本功能,盡管很多Application Server提供了這些基本組件,但很多應用開發(fā)者為了管理的更大的靈活性還是喜歡采用關系數(shù)據(jù)庫來管理用戶,懶惰的做法是用戶的密碼往往使用明文或簡單的變換后直接保存在數(shù)據(jù)庫中,因此這些用戶的密碼對軟件開發(fā)者或系統(tǒng)管理員來說可以說毫無保密可言,本文的目的是介紹MD5的Java Bean的實現(xiàn),同時給出用MD5來處理用戶的Account密碼的例子,這種方法使得管理員和程序設計者都無法看到用戶的密碼,盡管他們可以初始化它們。但重要的一點是對于用戶密碼設置習慣的保護
5.1 通過簡單的URLENCODE + BASE64編碼防止數(shù)據(jù)明文傳輸
5.2 對普通請求、返回數(shù)據(jù),生成MD5校驗(MD5中加入動態(tài)密鑰),進行數(shù)據(jù)完整性(簡單防篡改,安全性較低,優(yōu)點:快速)校驗。
5.3 對于重要數(shù)據(jù),使用RSA進行數(shù)字簽名,起到防篡改作用。
5.4 對于比較敏感的數(shù)據(jù),如用戶信息(登陸、注冊等),客戶端發(fā)送使用RSA加密,服務器返回使用DES(AES)加密。
原因:客戶端發(fā)送之所以使用RSA加密,是因為RSA解密需要知道服務器私鑰,而服務器私鑰一般盜取難度較大;如果使用DES的話,可以通過破解客戶端獲取密鑰,安全性較低。而服務器返回之所以使用DES,是因為不管使用DES還是RSA,密鑰(或私鑰)都存儲在客戶端,都存在被破解的風險,因此,需要采用動態(tài)密鑰,而RSA的密鑰生成比較復雜,不太適合動態(tài)密鑰,并且RSA速度相對較慢,所以選用DES)
把相關算法的代碼也貼一下吧 (其實使用一些成熟的第三方庫或許會來得更加簡單,不過自己寫,自由點)。注,這里的大部分加密算法都是參考一些現(xiàn)有成熟的算法,或者直接拿來用的。
1、MD5
//因為是使用category,所以木有參數(shù)傳入啦
-(NSString *) stringFromMD5 {
if(self == nil || [self length] == 0) {
return nil;
}
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return [outputString autorelease];
}
2、Base64
+ (NSString *) base64EncodeData: (NSData *) objData {
const unsigned char * objRawData = [objData bytes];
char * objPointer;
char * strResult;
// Get the Raw Data length and ensure we actually have data
int intLength = [objData length];
if (intLength == 0) return nil;
// Setup the String-based Result placeholder and pointer within that placeholder
strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char));
objPointer = strResult;
// Iterate through everything
while (intLength 2) { // keep going until we have less than 24 bits
*objPointer++ = _base64EncodingTable[objRawData[0] 2];
*objPointer++ = _base64EncodingTable[((objRawData[0] 0x03) 4) + (objRawData[1] 4)];
*objPointer++ = _base64EncodingTable[((objRawData[1] 0x0f) 2) + (objRawData[2] 6)];
*objPointer++ = _base64EncodingTable[objRawData[2] 0x3f];
// we just handled 3 octets (24 bits) of data
objRawData += 3;
intLength -= 3;
}
// now deal with the tail end of things
if (intLength != 0) {
*objPointer++ = _base64EncodingTable[objRawData[0] 2];
if (intLength 1) {
*objPointer++ = _base64EncodingTable[((objRawData[0] 0x03) 4) + (objRawData[1] 4)];
*objPointer++ = _base64EncodingTable[(objRawData[1] 0x0f) 2];
*objPointer++ = '=';
} else {
*objPointer++ = _base64EncodingTable[(objRawData[0] 0x03) 4];
*objPointer++ = '=';
*objPointer++ = '=';
}
}
// Terminate the string-based result
*objPointer = '\0';
NSString *rstStr = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];
free(objPointer);
return rstStr;
}
3、AES
-(NSData*) EncryptAES: (NSString *) key {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
4、RSA
- (NSData *) encryptWithData:(NSData *)content {
size_t plainLen = [content length];
if (plainLen maxPlainLen) {
NSLog(@"content(%ld) is too long, must %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];
size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
plainLen, cipher, cipherLen);
NSData *result = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
MD5加密算法原理MD5的全稱是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest開發(fā)出來,經(jīng)MD2、MD3和MD4發(fā)展而來。它的作用是讓大容量信息在用數(shù)字簽名軟件簽署私人密匙前被"壓縮"成一種保密的格式(就是把一個任意長度的字節(jié)串變換成一定長的大整數(shù))。不管是MD2、MD4還是MD5,它們都需要獲得一個隨機長度的信息并產(chǎn)生一個128位的信息摘要。雖然這些算法的結(jié)構(gòu)或多或少有些相似,但MD2的設計與MD4和MD5完全不同,那是因為MD2是為8位機器做過設計優(yōu)化的,而MD4和MD5卻是面向32位的電腦。這三個算法的描述和C語言源代碼在Internet RFCs 1321中有詳細的描述( ),這是一份最權威的文檔,由Ronald L. Rivest在1992年8月向IEFT提交。. .
//MD5加密方法
-(NSString *)md5:(NSString *)input{
const char *cStr = [input UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr, strlen(cStr), digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return? output;
}
//調(diào)用MD5方法:
NSString *str = @"123456";
NSString *result = [self md5:str];
NSLog(@"%@",result);
base64加密
NSString *urlStr = @"?";
//加密
NSData *bodyData = [urlStr dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"bodyData---%@",bodyData);
NSString *base64Str = [bodyData base64EncodedStringWithOptions:0];
NSLog(@"base64----%@",base64Str);
NSString *urlString = [urlStr stringByAppendingString:base64Str];
NSURL *urlShare = [NSURL URLWithString:urlString];
//解
NSData *jieData = [[NSData alloc] initWithBase64EncodedString:base64Str options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSString *jieStr = [[NSString alloc] initWithData:jieData encoding:NSUTF8StringEncoding];
NSLog(@"jieStr---%@",jieStr);