iPhoneでAES128暗号化
iPhoneアプリ開発で暗号化を行う必要が出てきたので、試しに書いてみました。
暗号方式にはAES128を、Padding方式にはPKCS7を使っています。
ここで使っているCommonCryptoはiOS SDKについてくるものですが、mac上でも普通に使うことができます(iPhone Simulator用のライブラリを無理矢理使います)。
使い方としては、下のコードをコンパイルして、
$ ./a.out aaaabbbbccccdddd eeeeffffgggghhhh message
というようにすると"message"が暗号化され、さらに続けて復号化されます。
第一引数は鍵、第二引数はInitial Vectorです。どちらも16バイトである必要があります。
/* * gcc -std=c99 crypto.m -framework Foundation */ #import <Foundation/Foundation.h> #import <CommonCrypto/CommonCryptor.h> @interface NSData (AES) - (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv; - (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv; - (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv; @end @implementation NSData (AES) - (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv { char keyPtr[kCCKeySizeAES128 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, sizeof(ivPtr)); [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesCrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCBlockSizeAES128, ivPtr, [self bytes], dataLength, buffer, bufferSize, &numBytesCrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; } free(buffer); return nil; } - (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv { return [self AES128Operation:kCCEncrypt key:key iv:iv]; } - (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv { return [self AES128Operation:kCCDecrypt key:key iv:iv]; } @end int main(int argc, char const* argv[]) { NSAutoreleasePool* pool; pool = [[NSAutoreleasePool alloc] init]; NSString *key = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding]; NSString *iv = [NSString stringWithCString:argv[2] encoding:NSUTF8StringEncoding]; NSString *data_str = [NSString stringWithCString:argv[3] encoding:NSUTF8StringEncoding]; NSData *data = [data_str dataUsingEncoding:NSUTF8StringEncoding]; NSData *en_data = [data AES128EncryptWithKey:key iv:iv]; NSData *de_data = [en_data AES128DecryptWithKey:key iv:iv]; NSString *de_str = [[[NSString alloc] initWithData:de_data encoding:NSUTF8StringEncoding] autorelease]; NSLog(@"%@", en_data); NSLog(@"%@", de_str); [pool drain]; return 0; }
暗号の話は難しいですね。勉強が必要です。
補足(2011/10/18):
CCCryptはデフォルトでCBC(cipher block chaining)を使うようになっています。ECB(electronic codebook)を指定することもできますが、使う理由は特にないでしょう。