iOS開發之演算法加密md5,sha1,AES,base64

來源:互聯網
上載者:User

1. md5:

      MD5即Message-Digest Algorithm 5(資訊-摘要演算法5),用於確保資訊傳輸完整一致。是電腦廣泛使用的雜湊演算法之一(又譯摘要演算法、雜湊演算法),主流程式設計語言普遍已有MD5實現。MD5的作用是讓大容量資訊在用數位簽章軟體簽署私人密鑰前被"壓縮"成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進位數字串)。(引用自百度百科)

MD5加密目前來說是無法復原的,只能用作一些檢驗過程,不能恢複其原文。

      MD5演算法產生的是固定的128bit,即128個0和1的二進位位,而在實際應用開發中,通常是以16進位輸出的,所以正好就是32位的16進位數,說白了也就是32個16進位的數字。

需要引入標頭檔:

#import <CommonCrypto/CommonDigest.h>

#define CC_MD5_DIGEST_LENGTH    16          /* digest length in bytes */
- (NSString *)md5:(NSDictionary *)paramsDict {NSString *inString = [paramsDict stringValueForKey:@"data" defaultValue:@""];    if (inString.length <= 0) {        return @"";    } else {        const char *cStrValue = [inString UTF8String];        //開闢一個16位元組(128位:md5加密出來就是128位/bit)的空間(一個位元組=8字位=8個位元)        unsigned char outResult[CC_MD5_DIGEST_LENGTH];        CC_MD5(cStrValue, strlen(cStrValue), outResult);                //x表示十六進位,X  意思是不足兩位將用0補齊,如果多餘兩位則不影響        NSString *outString =        [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",               outResult[0], outResult[1], outResult[2], outResult[3],               outResult[4], outResult[5], outResult[6], outResult[7],               outResult[8], outResult[9], outResult[10], outResult[11],               outResult[12], outResult[13], outResult[14], outResult[15]];        /*        //方法二:        NSMutableString *outString = [NSMutableString string];        for (int i = 0; i < 16; i++) {             [outString appendFormat:@"X", outResult[i]];        }        */        return outString;    } }

     為什麼是[16]呢,這是因為MD5演算法最後產生的是128位,而在電腦的最小儲存單位為位元組,1個位元組是8位,對應一個char類型,計算可得需要16個char。所以result是[16]。那麼為什麼輸出的格式一定是%02x呢,而不是其它呢。這也是有原因的:因為約定MD5一般是以16進位的格式輸出,那麼其實這個問題就轉換為把128個0和1以16進位來表示,每4位二進位對應一個16進位的元素,則需要32個16進位的元素,如果元素全部為0,放到char的數組中,正常是不會輸出,如00001111,以%x輸出,則是f,那麼就會丟失0;但如果以%02x表示則輸出結果是0f,正好是轉換的正確結果。

 

2. sha1 加密

 SHA1 演算法一樣無法復原。

- (NSString *) sha1:(NSString *)input{    const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];    NSData *data = [NSData dataWithBytes:cstr length:input.length];    //#define CC_SHA1_DIGEST_LENGTH   20       /* digest length in bytes */    uint8_t digest[CC_SHA1_DIGEST_LENGTH];    CC_SHA1(data.bytes, data.length, digest);        NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];    for(int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {         [output appendFormat:@"%02x", digest[i]];    }    return output;}

 

3. AES 加密

進階加密標準(Advanced Encryption Standard,AES),又稱Rijndael加密法。

需要注意的是,AES並不能作為HASH演算法,加密並解密後的結果,並不一定與原文相同,使用時請注意進行結果驗算。例如解密原文的長度,格式規則等。

需要引入標頭檔

#import <CommonCrypto/CommonCryptor.h>

加密和解密方法使用的參數密鑰可以均為32位長度的字串,可以將任意的字串經過md5計算32位字串作為密鑰,也可以自訂如:

#define APP_PUBLIC_PASSWORD     @"boundary"

- (NSData *)AES256EncryptWithKey:(NSString *)key  withString:(NSString *) inputString { //加密        NSData *inData = [inString dataUsingEncoding:NSUTF8StringEncoding];        /***        //如果希望返回字串,在開始時就開始對 NSData 做轉換, 對應下面方法三,方法一和二使用上面語句即可        const char *cstr = [inString cStringUsingEncoding:NSUTF8StringEncoding];        NSData *inData = [NSData dataWithBytes:cstr length:inString.length];       ***/        char keyPtr[kCCKeySizeAES256+1];        bzero(keyPtr, sizeof(keyPtr));        [APP_PUBLIC_PASSWORD getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];        NSUInteger dataLength = [inData length];        size_t bufferSize = dataLength + kCCBlockSizeAES128;        void *buffer = malloc(bufferSize);        size_t numBytesEncrypted = 0;        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,                                               kCCAlgorithmAES128,                                              kCCOptionPKCS7Padding | kCCOptionECBMode,                                              keyPtr, kCCBlockSizeAES128,                                              NULL,                                              [inData bytes],                                               dataLength,                                              buffer, bufferSize,                                              &numBytesEncrypted);        if (cryptStatus == kCCSuccess) {            NSData *outData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];            return outData;           /***             //如果需要返回 NSString 類型的結果,這裡需要進行轉換:             // 方法一:                 NSString *outString = [[NSString alloc]initWithData:outData encoding:NSUTF8StringEncoding];                    //失敗,注意:這裡 outString 為 nil,具體原因貌似是因為 NSData 內容含有非encoding編碼的字元             // 方法二:                 NSString *outString = [outData base64Encoding];             // 方法三:(轉換為2進位字串)                 if (outData && outData.length > 0) {                       Byte *datas = (Byte*)[outData bytes];                       NSMutableString *outString = [NSMutableString stringWithCapacity:outData.length * 2];                       for(int i = 0; i < outData.length; i++){                             [outString appendFormat:@"%02x", datas[i]];                       }                  }            ***/        }         free(buffer);        return nil;}
//解密可以直接使用加密得到的結果 NSData, 這樣將很容易,不必進行字元轉換- (NSData *)AES256DecryptWithKey:(NSString *)key withNSData:(NSString *)inData {//解密/***- (NSData *)AES256DecryptWithKey:(NSString *)key withString:(NSString *)inputString {//解密        //對應密碼編譯演算法中的方法二:(解密前進行GTMBase64編碼)           NSData *inData = [GTMBase64 decodeString:inString];        //對應密碼編譯演算法中的方法三:           NSMutableData *inData = [NSMutableData dataWithCapacity:inString.length / 2];           unsigned char whole_byte;           char byte_chars[3] = {'\0','\0','\0'};           int i;           for (i=0; i < [inString length] / 2; i++) {               byte_chars[0] = [inString characterAtIndex:i*2];               byte_chars[1] = [inString characterAtIndex:i*2+1];               whole_byte = strtol(byte_chars, NULL, 16);               [inData appendBytes:&whole_byte length:1];           } ***/                char keyPtr[kCCKeySizeAES256+1];        bzero(keyPtr, sizeof(keyPtr));        //使用 "key": #define APP_PUBLIC_PASSWORD     @"boundary"        [APP_PUBLIC_PASSWORD getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];        NSUInteger dataLength = [inData length];        size_t bufferSize = dataLength + kCCBlockSizeAES128;        void *buffer = malloc(bufferSize);        size_t numBytesDecrypted = 0;        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,                                           kCCAlgorithmAES128,                                 kCCOptionPKCS7Padding | kCCOptionECBMode,                                 keyPtr, kCCBlockSizeAES128,                                 NULL,                                 [inData bytes], dataLength,                                 buffer, bufferSize,                                 &numBytesDecrypted);        if (cryptStatus == kCCSuccess) {            NSData *outData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];            return outData;            /***            //若需返回 NSString,需要上面密碼編譯演算法和解密演算法的各個方法對應好,使用下列語句才不會返回 nil; 切記 dataLength 一定匹配好            NSString *outString = [[NSString alloc]initWithData:outData encoding:NSUTF8StringEncoding];            ***/        }        free(buffer);        return nil;}

 

4. base 64 密碼編譯演算法

下載庫 GTMBase64

 

執行個體demo: http://up.2cto.com/2012/1215/20121215123257741.zip

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.