【Objective-c】【C#】AESで暗号化・復号化
【追記】2014/10/20
これJava系(Android)とのやりとりでも使える・・・はずw
iOSとASP .NET MVC Web API間で暗号化・復号化するときですねー
OpenSSL途中まで実装したけどAES128に妥協しました。はい。
とゆーことで、今日もさらしますよー
Objective-c側
なお、base64エンコーディングは以下を使用させてもらっています。
そしてもちろんiOS側はてきとーでございます。嫌いなんじゃ。iOS。
https://github.com/l4u/NSData-Base64
HttpSecurity.h
@interface HttpSecurity : NSObject + (NSString *)AESEncrypt:(NSString *)source key:(NSString *)key; + (NSString *)AESDecrypt:(NSString *)source key:(NSString *)key; @end
HttpSecurity.m
#import "HttpSecurity.h" #import <CommonCrypto/CommonCryptor.h> @implementation HttpSecurity NSString * const IV = @"!QAZS2WS9SX#CRFV"; + (NSString *)AESEncrypt:(NSString *)source key:(NSString *)key { char keyPtr[kCCKeySizeAES128 + 1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; bzero(ivPtr, sizeof(ivPtr)); [IV getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData *sourceData = [source dataUsingEncoding:NSUTF8StringEncoding]; size_t bufferSize = sourceData.length + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCBlockSizeAES128, ivPtr, sourceData.bytes, sourceData.length, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) return [[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] base64EncodedString]; free(buffer); return nil; } + (NSString *)AESDecrypt:(NSString *)source key:(NSString *)key { char keyPtr[kCCKeySizeAES128 + 1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; bzero(ivPtr, sizeof(ivPtr)); [IV getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData *sourceData = [NSData dataFromBase64String:source]; size_t bufferSize = sourceData.length + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCBlockSizeAES128, ivPtr, sourceData.bytes, sourceData.length, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) return [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted] encoding:NSUTF8StringEncoding]; free(buffer); return nil; } @end
C#側
public class WebSecurity { /// <summary> /// ブロックサイズ /// </summary> private const int aesBlockSize = 128; /// <summary> /// 鍵長 /// </summary> private const int aesKeySize = 128; /// <summary> /// エンコーディング /// </summary> private static Encoding aesEncoding = Encoding.UTF8; /// <summary> /// 初期ベクタ /// </summary> private const string aesIV = "!QAZS2WS9SX#CRFV"; /// <summary> /// 文字列を指定した鍵で暗号化 /// </summary> /// <param name="source">暗号対象文字列</param> /// <param name="key">鍵</param> public static string AesEncrypt(string source, string key) { using (var provider = CreateAesProvider(key)) { var sourceBytes = aesEncoding.GetBytes(source); using (var encryptor = provider.CreateEncryptor()) { var retBytes = encryptor.TransformFinalBlock(sourceBytes, 0, sourceBytes.Length); return Convert.ToBase64String(retBytes); } } } /// <summary> /// 指定した鍵で復号化 /// </summary> /// <param name="source">復号対象文字列</param> /// <param name="key">鍵</param> public static string AesDecrypt(string source, string key) { using (var provider = CreateAesProvider(key)) { var sourceBytes = Convert.FromBase64String(source); using (var decryptor = provider.CreateDecryptor()) { var retBytes = decryptor.TransformFinalBlock(sourceBytes, 0, sourceBytes.Length); return aesEncoding.GetString(retBytes); } } } /// <summary> /// AESプロバイダー生成 /// </summary> /// <param name="key">鍵</param> private static AesCryptoServiceProvider CreateAesProvider(string key) { var provider = new AesCryptoServiceProvider(); provider.BlockSize = aesBlockSize; provider.KeySize = aesKeySize; provider.IV = aesEncoding.GetBytes(aesIV); provider.Key = aesEncoding.GetBytes(key); provider.Mode = CipherMode.CBC; provider.Padding = PaddingMode.PKCS7; return provider; } }