Skip to content

Instantly share code, notes, and snippets.

@yatatsu
Created October 24, 2014 11:02
Show Gist options
  • Save yatatsu/88b8f393d118c9952dd8 to your computer and use it in GitHub Desktop.
Save yatatsu/88b8f393d118c9952dd8 to your computer and use it in GitHub Desktop.
NSDate+AES
#import <Foundation/Foundation.h>
@interface NSData (AES)
- (NSData *)AES256EncryptWithPassphrase:(NSString *)pass;
- (NSData *)AES256DecryptWithPassphrase:(NSString *)pass;
@end
#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#define kDictKey @"key"
#define kDictIv @"iv"
#define kIterationCount 2048
@implementation NSData(AES)
- (NSData *)AES256EncryptWithPassphrase:(NSString *)pass
{
return [self AES256Operation:kCCEncrypt passphrase:pass];
}
- (NSData *)AES256DecryptWithPassphrase:(NSString *)pass
{
return [self AES256Operation:kCCDecrypt passphrase:pass];
}
- (NSData *)AES256Operation:(CCOperation)operation passphrase:(NSString *)pass
{
// generate key and iv
NSDictionary *keyIv = [NSData generateKeyIvFromPass:[pass dataUsingEncoding:NSUTF8StringEncoding]
salt:nil
iterationCount:kIterationCount];
// key
NSData *key = keyIv[kDictKey];
Byte *keyByte = (Byte *)malloc(key.length);
memcpy(keyByte, key.bytes, key.length);
// IV
NSData *iv = keyIv[kDictIv];
Byte *ivByte = (Byte *)malloc(iv.length);
memcpy(ivByte, iv.bytes, iv.length);
// out
NSUInteger dataLen = [self length];
size_t bufferSize = dataLen + kCCKeySizeAES256;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyByte,
kCCKeySizeAES256,
ivByte,
self.bytes,
dataLen,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
+ (NSDictionary *)generateKeyIvFromPass:(NSData *)pass
salt:(NSData *)salt
iterationCount:(NSInteger)count
{
int ivLen = kCCBlockSizeAES128;
int keyLen = kCCKeySizeAES256;
int keyIvLen = ivLen + keyLen;
NSMutableData *keyIv = [NSMutableData new];
NSMutableData *buff = [NSMutableData new];
while (keyIv.length < keyIvLen) {
[buff appendData:pass];
if (salt) [buff appendData:salt];
for (int i = 0; i < count; i++) {
buff.data = [buff MD5Digest];
}
[keyIv appendData:buff];
}
NSData* key = [keyIv subdataWithRange:NSMakeRange(0, keyLen)];
NSData* iv = [keyIv subdataWithRange:NSMakeRange(keyLen, ivLen)];
return @{kDictKey:key, kDictIv:iv};
}
- (NSData *)MD5Digest
{
unsigned char md5Buff[CC_MD5_DIGEST_LENGTH];
CC_MD5(self.bytes, self.length, md5Buff);
return [NSData dataWithBytes:(const void *)md5Buff length:sizeof(unsigned char)*CC_MD5_DIGEST_LENGTH];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment