iOS应用开发流程之加密工具类

lzy_lovesun 8年前
   <p>我建议先将基础的工具加入项目,后续的开发效率会呈指数增长。如果在专注功能开发过程中,才发现缺少大量常用的工具,不仅会打断思路,还会拖慢开发节奏。</p>    <p>当然,在每个项目开始的时候,不可能将全部工具都准备充分,只能依据个人的经验来评估需要提前准备的工具。</p>    <p>一个好的工匠,必须要有一个好的工具箱,并且还要不断优化它。</p>    <p>稍微扩展一下项目架构。</p>    <p>1.在base目录下为项目增加“Utilities”文件夹作为工具箱,并创建“Utilities.h”头文件,在PrefixHeader.pch中引用该头文件</p>    <p>2.暂时先创建三个NSObject子类“StringHelper”,“ImageHelper”,“EncryptionHelper”,作为三个工具类,并加入Utilities.h的引用列表</p>    <p>3.在base目录下再增加两个结构“Categories”和“Libraries”,分别用于存放分类和类库</p>    <p>4.我进一步将类库分为了第三方类库和自创建类库</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ee5023fdd21d90e08583c7e0cd3395b0.png"></p>    <h3><strong>加密工具类EncryptionHelper</strong></h3>    <p>暂时记录了base64编码和解码,MD2、MD4、MD5、SHA1、SHA224、SHA256、SHA384、SHA512加密,AES、DES加密和解密。</p>    <p>1.base64编码和解码</p>    <p>因为使用了Google的GTMBase64类库,所以讲此类库加入第三方库目录。</p>    <p>此类库代码中使用了autorelease将对象加入自动释放池,在ARC的项目中,可以将用到此类代码清除。</p>    <p>也可以在项目Target ->Build Phases ->Compile Sources,找到GTMBase64.m,双击后,在右边输入框内输入-fno-objc-arc,将此文件移除ARC管理。</p>    <p>在EncryptionHelper.m中引用GTMBase64.h后,可以实现如下方法:</p>    <pre>  <code class="language-objectivec">+ (NSString *)base64EncodeWithString:(NSString *)string  {      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];            NSString *result = [GTMBase64 stringByEncodingData:data];            return result;  }    + (NSString *)decodeBase64WithString:(NSString *)string  {      NSData *data = [GTMBase64 decodeString:string];            NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];            return result;  }  </code></pre>    <p>2.MD5加密</p>    <p>因为不可逆(大概可以理解为无数多解的二元一次方程),所以就只有加密算法可记录</p>    <pre>  <code class="language-objectivec">+ (NSString *)MD5SumWithString:(NSString *)string  {      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];            uint8_t buffer[CC_MD5_DIGEST_LENGTH];        CC_MD5(data.bytes, (CC_LONG)data.length, buffer);            //如下注释代码与上述加密代码等效  //    data = [data MD5Sum];  //    Byte *buffer = (Byte *)data.bytes;            NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];            for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++){          [result appendFormat:@"%02x", buffer[i]];      }            return result;  }  </code></pre>    <p>说明:</p>    <p>A.需要特别强调的一点,看到许多开发者都采用如下方法将NSString转为NSData:</p>    <p>const char *cstr = [string cStringUsingEncoding : NSUTF8StringEncoding ];</p>    <p>NSData *data = [ NSData dataWithBytes :cstr length :string. length ];</p>    <p><strong>我不建议采用上述代码,经过测试,当字符串为纯英文字母、数字、符号时候,结果无异;但是当字符串包含中文时候,string. length取到的长度就有问题,因为一个中文字符转为NSData以后长度大于1,所以上述方法将导致中文转化后,内容丢失!</strong></p>    <p>建议使用如下方法:NSData *data = [string dataUsingEncoding : NSUTF8StringEncoding ];</p>    <p>B.MD2、MD4、SHA1、SHA224、SHA256、SHA384、SHA512加密算法,只需要将示例代码中buffer的长度 CC_MD5_DIGEST_LENGTH 和加密方法 CC_MD5 更换为对应名称即可。</p>    <p>C.注释代码作用与前两行一致。不过需要引用分类 NSData+CommonCrypto.h。</p>    <p>D.data.bytes可以强转为(Byte *)和(char *),可以参考下述代码</p>    <p>E.result字符串的预留长度为CC_MD5_DIGEST_LENGTH * 2,因为buffer数组中元素类型为uint8_t(也就是unsigned char),在字符串格式化时候,以16进制形式显示两位,所以长度为2倍</p>    <p>F.%02x占位符表示以16进制显示两位,位数不足左边补0</p>    <p>3.AES、DES加密和解密</p>    <p>AES 和 DES 加密过程: string -> data -> AES/DES encrypt -> base64 encode -> string; 解密过程为逆向</p>    <pre>  <code class="language-objectivec">+ (NSString *)AES256EncryptedString:(NSString *)string usingKey:(NSString *)key  {      NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];      NSData *encryptedData = [data AES256EncryptedDataUsingKey:key error:nil];      NSData *base64Data = [GTMBase64 encodeData:encryptedData];            NSString *result = [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];        //    const char *buffer = (char *)base64Data.bytes;  //    result = [[NSString alloc] initWithCString:buffer encoding:NSUTF8StringEncoding];  //    result = [[NSString alloc] initWithBytes:base64Data.bytes length:base64Data.length encoding:NSUTF8StringEncoding];          return result;  }    + (NSString *)decryptedAES256String:(NSString *)string usingKey:(NSString *)key  {      NSData *base64Data = [string dataUsingEncoding:NSUTF8StringEncoding];      NSData *decryptedData = [GTMBase64 decodeData:base64Data];      NSData *data = [decryptedData decryptedAES256DataUsingKey:key error:nil];            NSString* result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];            return result;  }  </code></pre>    <p>此处增加了一个分类NSData+CommonCrypto,并在EncryptionHelper.m中引用,提供了AES和DES加密解密算法,感兴趣的朋友可以细看。</p>    <p>Github地址:https://github.com/ALongWay/AESCrypt-ObjC</p>    <p>说明:</p>    <p>A.AES加密方法中,生成result字符串,罗列了3种方式</p>    <p>B.DES加密过程中,只需将 AES256EncryptedDataUsingKey替换为 DESEncryptedDataUsingKey方法</p>    <p>C.DES解密过程中,只需将 decryptedAES256DataUsingKey替换为 decryptedDESDataUsingKey方法</p>    <p>罗列一下测试代码输出结果:</p>    <pre>  <code class="language-objectivec">    NSString *message = @"测试各种加密解密方法abc123+=/";      NSString *key = @"xyz123这是key";            NSString *base64Msg = [EncryptionHelper base64EncodeWithString:message];      NSString *decodeMsg= [EncryptionHelper decodeBase64WithString:base64Msg];            NSString *md5Msg = [EncryptionHelper MD5SumWithString:message];      NSString *sha1Msg = [EncryptionHelper SHA1HashWithString:message];      NSString *sha256Msg = [EncryptionHelper SHA256HashWithString:message];            NSString *aes256Msg = [EncryptionHelper AES256EncryptedString:message usingKey:key];      NSString *decryptedAESMsg = [EncryptionHelper decryptedAES256String:aes256Msg usingKey:key];            NSString *desMsg = [EncryptionHelper DESEncryptedString:message usingKey:key];      NSString *decryptedDESMsg = [EncryptionHelper decryptedDESString:desMsg usingKey:key];  </code></pre>    <pre>  <code class="language-objectivec">2016-09-08 17:46:43.505 base[7128:9029057] message:测试各种加密解密方法abc123+=/; key:xyz123这是key  2016-09-08 17:46:43.506 base[7128:9029057] base64Msg:5rWL6K+V5ZCE56eN5Yqg5a+G6Kej5a+G5pa55rOVYWJjMTIzKz0v  2016-09-08 17:46:43.506 base[7128:9029057] decodeMsg:测试各种加密解密方法abc123+=/  2016-09-08 17:46:43.506 base[7128:9029057] md5Msg:55d86b31f8cf9b3007a303664237fc8d  2016-09-08 17:46:43.506 base[7128:9029057] sha1Msg:1465c756f0eb64c7cccf175022a84ecd82f8faae  2016-09-08 17:46:43.506 base[7128:9029057] sha256Msg:297050d60416bbf0a84856fc9986a2bbe8a528a75377f7e1b011c4971c884a02  2016-09-08 17:46:43.506 base[7128:9029057] aes256Msg:seDPZ6RLHavklYxJOP9uMc7QoOZXZ8DASp6YHoe40B+6QkZ9Xhtn+Ecx5tPqakor  2016-09-08 17:46:43.506 base[7128:9029057] decryptedAESMsg:测试各种加密解密方法abc123+=/  2016-09-08 17:46:43.506 base[7128:9029057] desMsg:uXGaL4ChwSJt5HoD+gU9T/9L8K4eCVFEg5MyzivJRQxBRhAvfTou2Q==  2016-09-08 17:46:43.507 base[7128:9029057] decryptedDESMsg:测试各种加密解密方法abc123+=/  </code></pre>    <p> </p>    <p> </p>    <p> </p>    <p>来自:http://www.cnblogs.com/ALongWay/p/5853970.html</p>    <p> </p>