在某些考虑数据安全的场景下,我们常常会用到加密解密、编码解码知识。比如把用户密码保存到数据库上,常用的方式是通过MD5或SHA1不可逆算法进行加密后密文保存。
这里主要介绍三种常用的加密算法:
(1)不可逆:MD5、SHA1
(2)可逆:AES256
另外常用的编码方式:
(1)可逆:Base64
main.m
1 // 2 // main.m 3 // OCEncryptionAlgorithm: UTF8String, cStringUsingEncoding, dataUsingEncoding, base64EncodedStringWithOptions, initWithBase64EncodedString, initWithData (加密算法)(扩展知识:Base64编码) 4 // 5 // Created by 黄建武 on 15/5/12. 6 // Copyright (c) 2015年 Kenmu. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 #import "KMEncryption.h" 11 12 int main(int argc, const char * argv[]) { 13 @autoreleasepool { 14 //-------------------------MD5加密和SHA1加密 15 NSString *strSource = @"Kenmu-啊武"; 16 NSLog(@"“%@”的MD5加密数据为:“%@”", strSource, [KMEncryption encryptByMD5:strSource]); 17 18 NSLog(@"“%@”的SHA1加密数据为:“%@”", strSource, [KMEncryption encryptBySHA1:strSource]); 19 20 21 //-------------------------AES256加密解密 22 NSString *strKey = @"12345678901234567890123456789012"; //strKey必须是32字节 23 NSData *data = [KMEncryption encryptByAES256:strSource withKey:strKey]; 24 NSLog(@"“%@”的AES256加密数据为:“%@”", strSource, [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]); 25 26 strSource = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; 27 data = [KMEncryption decryptByAES256:strSource withKey:strKey]; 28 NSLog(@"“%@”的AES256解密数据为:“%@”", strSource, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); 29 30 //-------------------------Base64编码解码 31 strSource = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 32 NSLog(@"“%@”的Base64编码数据为:“%@”", strSource, [KMEncryption encodeBase64String:strSource]); 33 34 strSource = [KMEncryption encodeBase64String:strSource]; 35 NSLog(@"“%@”的Base64解码数据为:“%@”", strSource, [KMEncryption decodeBase64String:strSource]); 36 } 37 return 0; 38 }
KMEncryption.h
1 #import <Foundation/Foundation.h> 2 3 @interface KMEncryption : NSObject 4 /** 5 * MD5加密 6 * 7 * @param strSource 需要被加密的明文字符串 8 * 9 * @return MD5加密后的密文字符串 10 */ 11 + (NSString *)encryptByMD5:(NSString *)strSource; 12 13 /** 14 * SHA1加密 15 * 16 * @param strSource 需要被加密的明文字符串 17 * 18 * @return SHA1加密后的密文字符串 19 */ 20 + (NSString *)encryptBySHA1:(NSString *)strSource; 21 22 /** 23 * AES256加密 24 * 25 * @param strSource 需要被加密的明文字符串 26 * @param strKey 用于加密解密的32字节的密钥字符串(如不是32字节,就无法加密) 27 * 28 * @return AES256加密后的密文字符串 29 */ 30 + (NSData *)encryptByAES256:(NSString *)strSource withKey:(NSString *)strKey; 31 32 /** 33 * AES256解密 34 * 35 * @param strSource 需要被解密的密文字符串 36 * @param strKey 用于加密解密的32字节的密钥字符串(如不是32字节,就无法解密) 37 * 38 * @return AES256解密后的明文字符串 39 */ 40 + (NSData *)decryptByAES256:(NSString *)strSource withKey:(NSString *)strKey; 41 42 /** 43 * Base64编码 44 * 45 * @param strSource 需要被编码的字符串 46 * 47 * @return Base64编码后的字符串 48 */ 49 + (NSString *)encodeBase64String:(NSString *)strSource; 50 51 /** 52 * Base64解码 53 * 54 * @param strSource 需要被解码的字符串 55 * 56 * @return Base64解码后的字符串 57 */ 58 + (NSString *)decodeBase64String:(NSString *)strSource; 59 60 @end
KMEncryption.m
1 // 2 // KMEncryption.m 3 // OCEncryptionAlgorithm 4 // 5 // Created by 黄建武 on 15/5/12. 6 // Copyright (c) 2015年 Kenmu. All rights reserved. 7 // 8 9 #import "KMEncryption.h" 10 #import <CommonCrypto/CommonDigest.h> 11 #import <CommonCrypto/CommonCryptor.h> 12 13 @implementation KMEncryption 14 15 typedef NS_ENUM(NSUInteger, EncryptType) { 16 MD5, 17 SHA1 18 }; 19 20 #pragma mark - 私有方法 21 /** 22 * MD5或SHA1加密 23 * 24 * @param strSource 需要被加密的明文字符串 25 * @param encryptType 加密类型;例如:MD5、SHA1 26 * 27 * @return 加密后的密文字符串 28 */ 29 + (NSString *)encrypt:(NSString *)strSource encryptType:(EncryptType)encryptType { 30 NSString *strResult = nil; 31 const char *cSource = [strSource UTF8String]; //等同于[strSource cStringUsingEncoding:NSUTF8StringEncoding] 32 CC_LONG cSourceLen = (CC_LONG)strlen(cSource); 33 NSUInteger digestLen = 16; 34 unsigned char arrOutputDigest[digestLen]; 35 36 switch (encryptType) { 37 case MD5: { 38 CC_MD5(cSource, cSourceLen, arrOutputDigest); 39 break; 40 } 41 case SHA1: { 42 CC_SHA1(cSource, cSourceLen, arrOutputDigest); 43 break; 44 } 45 default: { 46 break; 47 } 48 } 49 50 NSMutableString *mStrResult = [[NSMutableString alloc] init]; 51 for (NSUInteger i=0; i<digestLen; i++) { 52 [mStrResult appendFormat:@"%02x", arrOutputDigest[i]]; //每个字符数组元素以(不足2位就补0的)16进制输出,16*2=32位 53 } 54 strResult = mStrResult; 55 return strResult; 56 } 57 58 /** 59 * AES256加密解密 60 * 61 * @param data 需要被加密解密的数据 62 * @param strKey 用于加密解密的32字节的密钥字符串(如不是32字节,就无法解密) 63 * @param isEncrypt 是否加密操作;YES为加密,NO为解密 64 * 65 * @return AES256加密解密后的数据 66 */ 67 + (NSData *)operationByAES256:(NSData *)data withKey:(NSString *)strKey isEncrypt:(BOOL)isEncrypt { 68 NSData *dataResult = nil; 69 NSUInteger dataLen = [data length]; 70 71 char keyPtr[kCCKeySizeAES256+1]; //kCCKeySizeAES256=32 72 bzero(keyPtr, sizeof(keyPtr)); 73 [strKey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 74 size_t bufferSize = dataLen + kCCBlockSizeAES128; //kCCBlockSizeAES128=16;//对于块加密算法,输出大小总是等于或小于输入大小加上一个块的大小,所以在下边需要再加上一个块的大小 75 void *buffer = malloc(bufferSize); 76 size_t numBytesOperated = 0; 77 CCCryptorStatus cryptStatus = CCCrypt(isEncrypt ? kCCEncrypt : kCCDecrypt, 78 kCCAlgorithmAES128, 79 kCCOptionPKCS7Padding | kCCOptionECBMode, 80 keyPtr, kCCBlockSizeAES128, 81 NULL, 82 [data bytes], dataLen, //输入 83 buffer, bufferSize, //输出 84 &numBytesOperated); 85 if (cryptStatus == kCCSuccess) { 86 dataResult = [NSData dataWithBytesNoCopy:buffer length:numBytesOperated]; 87 } 88 return dataResult; 89 } 90 91 #pragma mark - 公开方法 92 + (NSString *)encryptByMD5:(NSString *)strSource { 93 NSString *strResult = nil; 94 if (strSource && strSource.length > 0) { 95 strResult = [self encrypt:strSource encryptType:MD5]; 96 } 97 return strResult; 98 } 99 100 + (NSString *)encryptBySHA1:(NSString *)strSource { 101 NSString *strResult = nil; 102 if (strSource && strSource.length > 0) { 103 strResult = [self encrypt:strSource encryptType:SHA1]; 104 } 105 return strResult; 106 } 107 108 + (NSData *)encryptByAES256:(NSString *)strSource withKey:(NSString *)strKey { 109 NSData *dataResult = nil; 110 if (strSource && strSource.length > 0 && strKey && strKey.length == 32) { 111 dataResult = [strSource dataUsingEncoding:NSUTF8StringEncoding]; //编码 112 dataResult = [self operationByAES256:dataResult 113 withKey:strKey 114 isEncrypt:YES]; 115 } 116 return dataResult; 117 } 118 119 + (NSData *)decryptByAES256:(NSString *)strSource withKey:(NSString *)strKey { 120 NSData *dataResult = nil; 121 if (strSource && strSource.length > 0 && strKey && strKey.length == 32) { 122 dataResult = [[NSData alloc] initWithBase64EncodedString:strSource 123 options:NSDataBase64DecodingIgnoreUnknownCharacters]; //解码 124 dataResult = [self operationByAES256:dataResult 125 withKey:strKey 126 isEncrypt:NO]; 127 } 128 return dataResult; 129 } 130 131 + (NSString *)encodeBase64String:(NSString *)strSource { 132 NSData *data = [strSource dataUsingEncoding:NSUTF8StringEncoding]; 133 return [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; 134 } 135 136 + (NSString *)decodeBase64String:(NSString *)strSource { 137 NSData *data = [[NSData alloc] initWithBase64EncodedString:strSource 138 options:NSDataBase64DecodingIgnoreUnknownCharacters]; 139 return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 140 } 141 142 @end
结果:
1 2015-05-14 00:21:36.203 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的MD5加密数据为:“d33ee89d8ea08c8d258df20b7836bd02” 2 2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的SHA1加密数据为:“9bb7a793756842e38a76815bb03dd968” 3 2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的AES256加密数据为:“1KQQ/bVAkRszh8Ue18VzMQ==” 4 2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “1KQQ/bVAkRszh8Ue18VzMQ==”的AES256解密数据为:“Kenmu-啊武” 5 2015-05-14 00:21:36.204 OCEncryptionAlgorithm[1010:79295] “Kenmu-啊武”的Base64编码数据为:“S2VubXUt5ZWK5q2m” 6 2015-05-14 00:21:36.205 OCEncryptionAlgorithm[1010:79295] “S2VubXUt5ZWK5q2m”的Base64解码数据为:“Kenmu-啊武”