IOS中DES與MD5加密方案

nwbg 10年前發布 | 10K 次閱讀 Objective-C IOS MD5

項目中用的的加密算法,因為要和安卓版的適配,中間遇到許多麻煩。

MD5算法和DES算法是常見的兩種加密算法。

MD5:MD5是一種不可逆的加密算法,按我的理解,所謂不可逆,就是不能解密,那么它有什么用的,它的用處大了,大多數的登錄功能都會使用到這種算法。后面根據我的項目經驗來介紹。

DES:一種使用密鑰加密的塊算法,所以,使用它加密時,需要一個密鑰,加上一些設置和你需要加密的文段。

在IOS中,使用這兩種加密算法非常簡單,系統的<CommonCrypto/CommonCrypto.h>庫給我們提供的邊界的接口。在很多移動項目中,安卓平臺和IOS平臺的后臺服務是統一的,比如一個登錄功能是這樣的流程:

1、客戶端向服務端請求密鑰,請求的參數是雙方約定好的一個MD5加密的字符串。我們可以通過下面的進行第一步加密:

- (NSString *)MD5Digest
{
    //要進行UTF8的轉碼
    const char* input = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(input, (CC_LONG)strlen(input), result);
    
    NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [digest appendFormat:@"%02x", result[i]];
    }
    
    return digest;
}

通過這樣的方法,我們可以很容易的得到一串MD5加密字符串,但是一定要和后臺約定好,MD5加密的位數是16位還是32位,用上述方法加密出來的時32位,當然他們之間是有聯系的,通過下面的方法可以將其轉成16為:

+(NSString *)trransFromMD532ToMD516:(NSString *)MD532{
    NSString  * string;
    for (int i=0; i<24; i++) {
        string=[MD532 substringWithRange:NSMakeRange(8, 16)];
    }
    return string;
}

還有一點需要注意,加密后的大小寫也要對應。

2、服務端將得到的MD5串和以約定好的MD5串進行對比,如果一致,可以放行,返回密鑰。

3、客戶端取到密鑰,將密鑰再進行一次MD5加密,然后通過DES將要傳送的數據加密發給服務器。

這一步至關重要,我們先看DES的加密代碼

+(NSString *) encryptUseDES:(NSString *)clearText key:(NSString *)key andiv:(NSString *)iv
{
    //這個iv 是DES加密的初始化向量,可以用和密鑰一樣的MD5字符
    NSData * date = [iv dataUsingEncoding:NSUTF8StringEncoding];
    NSString *ciphertext = nil;
    NSUInteger dataLength = [clearText length];
    NSData *textData = [clearText dataUsingEncoding:NSUTF8StringEncoding];
    
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,//加密模式 kCCDecrypt 代表解密
                                          kCCAlgorithmDES,//加密方式
                                          kCCOptionPKCS7Padding,//填充算法
                                          [key UTF8String], //密鑰字符串
                                          kCCKeySizeDES,//加密位數
                                          [date bytes],//初始化向量
                                          [textData bytes]  ,
                                           dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSLog(@"DES加密成功");
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        Byte* bb = (Byte*)[data bytes];
        ciphertext = [Base64 parseByteArray2HexString:bb];
    }else{
        NSLog(@"DES加密失敗");
    }
    return ciphertext;
}

幾點注意:

(1)加密方式,IOS官方提供的是如下幾種

enum {
    kCCAlgorithmAES128 = 0,
    kCCAlgorithmAES = 0,
    kCCAlgorithmDES,
    kCCAlgorithm3DES,       
    kCCAlgorithmCAST,       
    kCCAlgorithmRC4,
    kCCAlgorithmRC2,   
    kCCAlgorithmBlowfish    
};

(2)填充算法

enum {
    /* options for block ciphers */
    kCCOptionPKCS7Padding   = 0x0001,
    kCCOptionECBMode        = 0x0002
    /* stream ciphers currently have no options */
};

我們可以發現,官方提供的只有這兩種,然而JAVA使用的卻是

kCCOptionPKCS7Padding

但是不用擔心,在密鑰是8位的時候,這兩種填充算法加密出來的結果試一模一樣的。

4、服務器通過相同的方式,解密出密文,通配安卓端。


 本文由用戶 nwbg 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!