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

开篇应该先说明一下这是我写的第一篇技术博客,水平高低的大家多提宝贵意见。
  最近做的一个和蓝牙交互的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,哈哈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容