IT虾米网

IOS中DES与MD5加密方案详解

developer 2018年06月23日 手机开发 425 0
项目中用的的加密算法,因为要和安卓版的适配,中间遇到许多麻烦。

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、服务器通过相同的方式,解密出密文,通配安卓端。


发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

iOS中url的特殊字符转换详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。