美文网首页
iOS 加密总结(Base64 、DES、MD5)

iOS 加密总结(Base64 、DES、MD5)

作者: AmdyTeng | 来源:发表于2017-01-19 18:11 被阅读590次

    开篇应该先说明一下这是我写的第一篇技术博客,水平高低的大家多提宝贵意见。
      最近做的一个和蓝牙交互的iOS APP,其中中用到了各种各样的加密和验证,包括:Base64 加解密、MD5 加密、DES 加解密、AES加解密、CRC验证等,其中还有16进制,ASCII码,NSdata 等各种数据之间的转换,而且也还用到了Socket 传输数据,涉及到的技术点比较多,这篇文章就简单总结一下加解密之间的问题吧。

    • Base 64 加解密
      Base 64 加解密 没有什么好说的,系统自带的办法就可以解决了,或者使用 第三方GTMBase64
    //Base64加密
    +(NSString *)encodeBase64:(NSString *)input{
        NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
        data = [GTMBase64 encodeData:data];
        NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"encodeBase64 == %@",base64String);
        return base64String;
    }
    
    //Base64编码
    +(NSString *)base64EncodeString:(NSString *)string
    {
        //1.先把字符串转换为二进制数据
        NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
        //2.对二进制数据进行base64编码,返回编码后的字符串
        //这是苹果已经给我们提供的方法
        NSString *str = [data base64EncodedStringWithOptions:0];
        return str;
    }
    
    //Base64解密
    +(NSString *)decodeBase64:(NSString *)input{
        NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
        data = [GTMBase64 decodeData:data];
        NSString *base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"decodeBase64 == %@",base64String);
        return base64String;
    }
    
    //对base64编码后的字符串进行解码
    +(NSString *)base64DecodeString:(NSString *)string
    {
        //1.将base64编码后的字符串『解码』为二进制数据
        //这是苹果已经给我们提供的方法
        NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:0];
        //2.把二进制数据转换为字符串返回
        NSString *str =  [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        return str;
    }
    
    //Base64 字符串解码成 字符串
    +(NSString *)decodeBase64ToHexString:(NSString *)input{
        //1.将base64编码后的字符串『解码』为二进制数据
        //这是苹果已经给我们提供的方法
        NSData *myD = [[NSData alloc]initWithBase64EncodedString:input options:0];
        Byte *bytes = (Byte *)[myD bytes];
        //下面是Byte 转换为16进制。
        NSString *hexStr=@"";
        for(int i=0;i<[myD length];i++)
        {
            NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
            if([newHexStr length]==1)
                hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
            else
                hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
        }
        return hexStr;
        
    }
    

    要使用DES加密,首先必须要引入 <CommonCrypto/CommonCrypto.h>
    我们常用的无非就是下面的这种加密方法:其中 plainText 使我们要传的 数据 Nsdata , key 是我们加密的 秘钥,是Byte格式的。

    //DES 加密
    +(NSData *)encryptUseDES:(NSData *)plainText key:(Byte *)key
    {
        NSData *textData = plainText;
        NSUInteger dataLength = [textData length];
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                              kCCOptionECBMode,
                                              key, kCCKeySizeDES,
                                              nil,
                                              [textData bytes], dataLength,
                                              buffer, 1024,
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
            return data;
        }
        return nil;
    }
    
    //DES 解密
    +(NSData *)decrypUseDES:(NSData *)plainText key:(Byte *)key{
        
        NSData *cipherdata = plainText;
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
                                              kCCOptionECBMode,
                                              key, kCCKeySizeDES,
                                              nil,
                                              [cipherdata bytes], [cipherdata length],
                                              buffer, 1024,
                                              &numBytesDecrypted);
        if(cryptStatus == kCCSuccess)
        {
            NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
            return plaindata;
        }
        return nil;
    }
    
    • MD5加密

    MD5 (Message Digest Algorithm MD5)是一种不可逆的加密方式,用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一。网上那些可以看到的解密MD5的都是自建了一个庞大的MD5加密之后结果的数据库,当解密的时候去查找,而并不是真正的解密。
      MD5其实进过算法产生的是固定的128bit,即128个0和1的二进制位,而在实际应用开发中,通常是以16进制输出的,所以正好就是32位的16进制,说白了也就是32个16进制的数字。

    如下,是MD5的 返回Nsdata 的加密方法。

    //MD5加密返回Nsdata
    +(NSData *)encodeMD5:(NSData *)input{
        
        unsigned char result[CC_MD5_DIGEST_LENGTH];
        CC_MD5(input.bytes, (CC_LONG)input.length, result);
        
        NSData *data =[[NSData alloc] initWithBytes:result length:CC_MD5_DIGEST_LENGTH];
        return data;
    }
    

    如下,生成是小写的MD5的字符串,如果要生成大写的,只需要把
    [ret appendFormat:@"%02X",result[i]];中的 "%02X"X改成小写的 x即可。

    //MD5加密返回Nsstring
    +(NSString *)MD5HexDigest:(NSData *)input {
        unsigned char result[CC_MD5_DIGEST_LENGTH];
        
        CC_MD5(input.bytes, (CC_LONG)input.length, result);
        NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
        for (int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
            [ret appendFormat:@"%02X",result[i]];
        }
        return ret;
    }
    

    如上, 其中%02x是格式控制符:‘x’表示以16进制输出,‘02’表示不足两位,前面补0;如‘f’输出为0f,‘1f3’则输出1f3; 其实CC_MD5_DIGEST_LENGTH 等于16,也就是说我们定义了一个字符数组result,并且是 16位的。那为什么是[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,正好是转换的正确结果。

    • 补充:NSdata 和 Byte 互相转换

    Nsdata ->Byte

    NSData *testData = [[NSData alloc]init];
    Byte *testByte = (Byte *)[testData bytes];
    
    

    Byte ->NSdata

     Byte bytes[]= {0X01,0X02,0X03,0X04,0X05,0X06};
     NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
    

    代码已经上传到GitHub:https://github.com/AmdyTeng/iOS-Encrypt
    欢迎提出宝贵意见,不吝啬的话来个Star,哈哈

    相关文章

      网友评论

          本文标题:iOS 加密总结(Base64 、DES、MD5)

          本文链接:https://www.haomeiwen.com/subject/pfwibttx.html