iOS开发之 AES+Base64数据混合加密与解密
"APP的数据安全已经牵动着我们开发者的心,简单的MD5/Base64等已经难以满足当下的数据安全标准,本文简单的介绍下AES与Base64的混合加密与解密"
AES:高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
以上是来自百度百科的解释。
下面我将用代码来阐述其使用方法。 首先我们创建一个NSData的类扩展,命名为AES,创建完如果对的话应该是这样的NSData+AES然后导入如下头文件
|
1
2
|
#import 《CommonCrypto/CommonDigest.h》#import 《CommonCrypto/CommonCryptor.h》 |
再增加加解密的方法,方便外部文件的调用,写完.h文件如下
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#import 《Foundation/Foundation.h》#import 《CommonCrypto/CommonDigest.h》#import 《CommonCrypto/CommonCryptor.h》@interface NSData (AES)//加密- (NSData *) AES256_Encrypt:(NSString *)key;//解密- (NSData *) AES256_Decrypt:(NSString *)key;//追加64编码- (NSString *)newStringInBase64FromData;//同上64编码+ (NSString*)base64encode:(NSString*)str;@end |
.m文件中依次实现这几个方法,具体如下
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#import "NSData+AES.h"static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";@implementation NSData (AES)//加密- (NSData *) AES256_Encrypt:(NSString *)key{ char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); return nil;} //解密- (NSData *) AES256_Decrypt:(NSString *)key{ char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil;} //追加64编码- (NSString *)newStringInBase64FromData { NSMutableString *dest = [[NSMutableString alloc] initWithString:@""]; unsigned char * working = (unsigned char *)[self bytes]; int srcLen = (int)[self length]; for (int i=0; i<srclen; i += 3) { for (int nib="0; nib= srcLen) break;" unsigned char curr =" ((working[i+byt] << (8-ix)) & 0x3F);" if (i+nib < srclen) curr |=" ((working[i+nib] ">> ix) & 0x3F); [dest appendFormat:@"%c", base64[curr]]; } } return dest;} + (NSString*)base64encode:(NSString*)str{ if ([str length] == 0) return @""; const char *source = [str UTF8String]; int strlength = (int)strlen(source); char *characters = malloc(((strlength + 2) / 3) * 4); if (characters == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (i < strlength) { char buffer[3] = {0,0,0}; short bufferLength = 0; while (bufferLength < 3 && i < strlength) buffer[bufferLength++] = source[i++]; characters[length++] = base64[(buffer[0] & 0xFC) >> 2]; characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; if (bufferLength > 1) characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; else characters[length++] = '='; if (bufferLength > 2) characters[length++] = base64[buffer[2] & 0x3F]; else characters[length++] = '='; } NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES]; return g;} @end</srclen; i += 3) {> |
AES+Base64的加密方式到此已经结束了,下面讲一下单纯的AES字符串加密的。
和上面的基本上差不多,写一个NSString的类扩展,命名为AES,创建完如果对的话应该是这样的NSString+AES导入如下头文件
|
1
|
#import "NSData+AES.h" |
同样的把加解密的方法写在.h文件中,写完如下
|
1
2
3
4
5
6
7
8
|
#import 《Foundation/Foundation.h》#import "NSData+AES.h"@interface NSString (AES)//加密- (NSString *) AES256_Encrypt:(NSString *)key;//解密- (NSString *) AES256_Decrypt:(NSString *)key;@end |
.m实现方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
//加密- (NSString *) AES256_Encrypt:(NSString *)key{ const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding]; NSData *data = [NSData dataWithBytes:cstr length:self.length]; //对数据进行加密 NSData *result = [data AES256_Encrypt:key]; //转换为2进制字符串 if (result && result.length > 0) { Byte *datas = (Byte*)[result bytes]; NSMutableString *output = [NSMutableString stringWithCapacity:result.length * 2]; for(int i = 0; i < result.length; i++){ [output appendFormat:@"x", datas[i]]; } return output; } return nil;}//解密- (NSString *) AES256_Decrypt:(NSString *)key{ //转换为2进制Data NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2]; unsigned char whole_byte; char byte_chars[3] = {'\0','\0','\0'}; int i; for (i=0; i < [self length] / 2; i++) { byte_chars[0] = [self characterAtIndex:i*2]; byte_chars[1] = [self characterAtIndex:i*2+1]; whole_byte = strtol(byte_chars, NULL, 16); [data appendBytes:&whole_byte length:1]; } //对数据进行解密 NSData* result = [data AES256_Decrypt:key]; if (result && result.length > 0) { return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]; } return nil;} |
到此我们加密的文件基本上都已经OK了,下面我们来简单的的使用一下,具体如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#import "ViewController.h"#import "NSString+AES.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //字符串加密 NSString *key = @"12345678";//Key是和后台约定的key哦,不然无法解密.... NSString *secret = @"aes Bison base64"; NSLog(@"字符串加密---%@",[secret AES256_Encrypt:key]); //字符串解密 NSLog(@"字符串解密---%@",[[secret AES256_Encrypt:key] AES256_Decrypt:key]); //NSData加密+base64 NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding]; NSData *cipher = [plain AES256_Encrypt:key]; NSLog(@"NSData加密+base64++++%@",[cipher newStringInBase64FromData]); //解密 plain = [cipher AES256_Decrypt:key]; NSLog(@"NSData解密+base64++++%@", [[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding]);}@end |
运行得到打印的结果如下:
2016-03-30 17:31:55.686 AES_256[14242:198853] 字符串加密---07815ca46d20acc3ba4e43d6930c7537496e851a36dbeac34fa30c5796089b02
2016-03-30 17:31:55.687 AES_256[14242:198853] 字符串解密---aes Bison base64
2016-03-30 17:31:55.687 AES_256[14242:198853] NSData加密+base64++++B4FcpG0grMO6TkPWkwx1N0luhRo22+rDT6MMV5YImwI
2016-03-30 17:31:55.687 AES_256[14242:198853] NSData解密+base64++++aes Bison base64
##值得注意的是Key是和后台约定的key哦,不然无法解密….
最后留下demo下载地址
iOS开发之 AES+Base64数据混合加密与解密的更多相关文章
- AES对数据进行加密与解密
AES对数据进行加密与解密随着对称密码的发展,DES数据加密标准算法由于密钥长度较小(56位),已经不适应当今分布式开放网络对数据加密安全性的要求,因此1997年NIST公开征集新的数据加密标准,即A ...
- iOS开发之JSON格式数据的生成与解析
本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据? ...
- 转载 -- iOS开发之JSON格式数据的生成与解析
本文将从四个方面对IOS开发中JSON格式数据的生成与解析进行讲解: 一.JSON是什么? 二.我们为什么要用JSON格式的数据? 三.如何生成JSON格式的数据? 四.如何解析JSON格式的数据? ...
- iOS 开发之 protocol Buffer 数据交换
前言: 从 14 年公司做项目时开始接触 Google 的 protocol Buffer,用了一段时间,后来到新公司就没有机会再使用了,趁着还没完全忘记,记录下. 简介:protocolbuffer ...
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- iOS开发之CoreData数据存储
iOS开发之CoreData数据存储 参考资料:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreD ...
- 前后端API交互数据加密——AES与RSA混合加密完整实例
前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...
- WebSocket数据加密——AES与RSA混合加密
前言 之前在写“一套简单的web即时通讯”,写到第三版的时候没什么思路,正好微信公众号看到一篇讲API交互加密,于是就自己搞了一套AES与RSA混合加密,无意中产生应用在WebSocket想法,好在思 ...
- iOS中使用RSA对数据进行加密解密
RSA算法是一种非对称加密算法,常被用于加密数据传输.如果配合上数字摘要算法, 也可以用于文件签名. 本文将讨论如何在iOS中使用RSA传输加密数据. 本文环境 mac os openssl-1.0. ...
随机推荐
- POJ 1795 DNA Laboratory(状压DP)
[题目链接] http://poj.org/problem?id=1795 [题目大意] 给出n个字符串,求一个最小长度的串,该串包含给出的所有字符串. 要求长度最小且字典序最小. [题解] dp[i ...
- BZOJ 3864 Hero Meets Devil
题目大意 给定一个由AGCT组成的串\(t\), 求对于所有的\(L \in [1, |t|]\), 有多少个由AGCT组成的串\(s\)满足\(LCS(s, t) = L\). Solution 传 ...
- Bluetooth篇 开发实例之九 和蓝牙模块通信
首先,我们要去连接蓝牙模块,那么,我们只要写客户端的程序就好了,蓝牙模块就相当于服务端. 连接就需要UUID. #蓝牙串口服务SerialPortServiceClass_UUID = ‘{00001 ...
- ES6里关于正则表达式的拓展
一.构造函数 在 ES5 中,RegExp构造函数的参数有两种情况. 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag) var regex = new RegExp('xy ...
- etcd的原理分析
k8s集群使用etcd作为它的数据后端,etcd是一种无状态的分布式数据存储集群. 数据以key-value的形式存储在其中. 今天同事针对etcd集群的运作原理做了一个讲座,总结一下. A. etc ...
- 使用老版本的java api提交hadoop作业
还是使用之前的单词计数的例子 自定义Mapper类 import java.io.IOException; import org.apache.hadoop.io.LongWritable; impo ...
- fabricjs 自定义类型
https://stackoverflow.com/questions/36660108/how-to-create-custom-fabricjs-object I have to create a ...
- 2017.4.19 慕课网-通过自动回复机器人学习mybatis
开发前的分析 1.技能前提 JSP JSTL EL JS/JQUERY Servlet JavaBean JDBC(后期再用mybatis,这样体会更深) MYSQL 2.需求分析和模块划分 (1)基 ...
- 阻止右键菜单(阻止默认事件)&&跟随鼠标移动(大图展示)&&自定义右键菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Win7安装了Visual Studio 2008没有快捷方式怎么办
在C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE,就是这个devenv.exe了
