在ios学习中大家都知道在iOS中使用AES进行媒体文件的加密与解密是一个非常难以实现的技术,很多同学都遇到过这个问题,在ios教程中有很多对此的解决办法,在这里通过一个实例为大家讲解如何实现这个功能。 之前使用过zipArchive来进行文件的加密,方法是先将文件生成一个带密码的自定义后缀的压缩包,然后读取的时候使用密码进行解压缩,文件读入内存后删除解压后的文件。测试后感觉速度还行,但是这个过程有点繁琐,而且可能不太适合较大的文件,于是考虑换用其它方式进行资源的加密。 今天要分享的是基于RNCryptor框架的AES加密方法,这个框架同时支持同步和异步读取加密文件,功能十分强大,而且提供了完整的展示用例和文档。下面给出下载地址:RNCryptor 首先我们来看看加密,我做了个Mac上的小工具来实现文件的加密。 功能很简单,就不多说了,以后可能会分享篇Mac开发入门的小文章,具体讲讲怎么做这样一个小工具。 下面这个方法是加密工具在读取文件后对数据进行加密,加了注释就不逐行说了:
- - (void)encrypt:(NSInteger)index {
- NSData *data = [NSData dataWithContentsOfURL:[contents objectAtIndex:index]];
- NSError *error = nil;
- NSData *encryptedData = [RNEncryptor encryptData:data
- withSettings:kRNCryptorAES256Settings
- password:PWD
- error:&error];
- //设置密码 使用AES加密读取到的数据
- NSAssert(!error, @"Load Data fail");
-
- NSFileManager *fm = [NSFileManager defaultManager];
- NSURL *url = [contents objectAtIndex:index];
- NSString *path = [[url path] stringByReplacingOccurrencesOfString:[url lastPathComponent] withString:[NSString stringWithFormat:@"f%ld.gwesley",index + 1]];
-
- //在原文件夹生成加密后的文件
- if (![fm createFileAtPath:path contents:encryptedData attributes:nil]) {
- NSLog(@"Error was code: %d - message: %s", errno, strerror(errno));
- //这样写是因为createFileAtPath这个方法只返回了一个布尔值,并没有具体的错误信息,使用errno可以解决这个问题
- } else {
-
- if (index < [contents count] - 1) {
- [self encrypt:++index];
- }
- }
- }
复制代码
这里生成的文件后缀.gwesley可以任意更换为自己喜欢的 接下来是读取数据然后进行解密
- NSString *path = [[NSBundle mainBundle] resourcePath];
- NSData *data = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/f%d.gwesley",path,index]];
- //读取加密数据
- NSError *error = nil;
- NSData *decryptData = [RNDecryptor decryptData:data withPassword:PWD error:&error];
- //使用密码得到解密后数据
- NSAssert(!error, @"Decrypt data fail");
- self.player = [[AVAudioPlayeralloc] initWithData:decryptData error:&error];
- //播放一下 看看数据是否正确
- NSAssert(!error, @"player init fail");
- self.player.delegate = self;
- [self.playerprepareToPlay];
- [self.player play];
- // 如果你在生成或读取文件的时候遇到了问题,可以看看下面对NSURL的属性介绍。
复制代码
简单说说NSURL这个类中的属性,我们读取文件时拿到的是文件的url,生成文件是要传的是path字符串。 使用[url path]可以很简单获得path,两者打印出来的时候有一些小差异,举个例子
- path : /Users/zhaohaobo/Music/Track01.mp3
- url : file://localhost/Users/zhaohaobo/Music/Track01.mp3
复制代码
通过url可以拿到很多的属性,通过一小段代码把这些属性给打印出来,方便写代码的时候进行参考:
- NSArray *list = [NSArray arrayWithObjects:@"absoluteString",@"absoluteURL",@"baseURL",@"fragment",@"host",
- @"lastPathComponent",@"parameterStringxtension",
- @"port",@"query",@"relativePath",@"relativeString",@"resourceSpecifier",@"scheme",@"standardizedURL",@"user", nil];
- for (NSString *ms in list) {
- SEL aSelector = NSSelectorFromString(ms);
- NSLog(@"%@ : %@", ms,[[contents objectAtIndex:0] performSelector:aSelector]);
- }
-
-
复制代码
打印结果如下: 2012-12-14 16:23:53.858 AESEncryptor[2282:403] absoluteString :file://localhost/Users/zhaohaobo/Music/Track01.mp3 2012-12-14 16:23:53.859 AESEncryptor[2282:403] absoluteURL : file://localhost/Users/zhaohaobo/Music/Track01.mp3 2012-12-14 16:23:53.859 AESEncryptor[2282:403] baseURL : (null) 2012-12-14 16:23:53.859 AESEncryptor[2282:403] fragment : (null) 2012-12-14 16:23:53.859 AESEncryptor[2282:403] host : localhost 2012-12-14 16:23:53.859 AESEncryptor[2282:403] lastPathComponent : Track01.mp3 2012-12-14 16:23:53.860 AESEncryptor[2282:403] parameterString : (null) 2012-12-14 16:23:53.860 AESEncryptor[2282:403] password : (null) 2012-12-14 16:23:53.860 AESEncryptor[2282:403] path : /Users/zhaohaobo/Music/Track01.mp3 2012-12-14 16:23:53.860 AESEncryptor[2282:403] pathComponents : ( "/", Users, zhaohaobo, Music, "Track01.mp3" ) |