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

2017-01-19  本文已影响590人  AmdyTeng

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

//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 (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 *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,哈哈

上一篇下一篇

猜你喜欢

热点阅读