私はPython(Google App Engine)からいくつかのデータを暗号化し、iOSで解読しようとしています。Google App Engine(Python)のAES暗号化とiOS(Objective-C)の復号化
これを取り巻くいくつかの問題は、AES暗号化では非常に多くのオプションがあり、PythonとObjective-Cではさまざまなフォーマットが利用できるという事実に基づいています。
Google App EngineのPyCryptoライブラリと、PKCS7Paddingを必要とするiOS/Objective-C側のAESコードの利用が限られているため、Python側でslowAESを使用することに決めました。
私は16ビットキー、CBCモード、PKCS7Paddingも使用しています。 Pythonの側で、私はデータを符号化、その後BASE64梱包、暗号化、および午前こと
def str2nums(s):
return map(ord, s)
key = "hjt4mndfy234n5fs"
moo = aes.AESModeOfOperation()
iv = [12, 34, 96, 15] * 4
CBC_mode = moo.modeOfOperation['CBC']
nkey = str2nums(key)
def encrypt(plaintext):
funcName = inspect.stack()[0][3]
logging.debug("Enter " + funcName)
logging.debug("Input string: " + plaintext)
m, s, encData = moo.encrypt(plaintext, CBC_mode, nkey, len(nkey), iv)
fmt = len(encData)*'B'
dataAsStr = ""
for j in encData:
dataAsStr = dataAsStr + str(j) + ","
logging.debug("Output encrypted data:[" + dataAsStr + "]")
encoded = base64.b64encode(struct.pack(fmt, *encData))
logging.debug("Output encrypted string: " + encoded)
decoded = struct.unpack(fmt, base64.b64decode(encoded))
decrypted = moo.decrypt(decoded, s, CBC_mode, nkey, len(nkey), iv)
logging.debug("Output decrypted back: " + decrypted)
return encoded
注:ことを考えると
が、これは私の暗号化機能とヘルパー変数/関数です。この暗号化されたデータを返す前に、私はまた、ログにそれが実際に動作することを示すために、復号化時にテストを実行しています。そのように/パック/暗号化されたデータを
- (NSData *)AES128DecryptWithKey:(NSString *)key {
// 'key' should be 16 bytes for AES128, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil;
}
そして、私はBASE64をプルダウンするとき、私はこれを利用しています:iOSの側では
、私は次のAES NSDataの加算を使用していNSMutableString * result = [[NSMutableString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
if (LOG) { NSLog(@"Base64 encoded/Encrypted string: %@", result); }
NSData* encryptedData = [NSData decodeBase64ForString:result]; // base64 decode
if (LOG) { NSLog(@"Encrypted string: %@", encryptedData); }
NSData* decryptedData = [encryptedData AES128DecryptWithKey:@"hjt4mndfy234n5fs"]; // AES Decrypt
問題は、サーバー上で(Pythonで)復号化しても、クライアント(iOS)側でデータを正しく復号化できないようです。
復号化中、cryptStatusは常に終了します。kCCAlignmentError。私はそれほど理解していません。
私はAES 256を使いこなしましたが、私は思うに32ビットのキーが必要です。それはCBCモードのslowAESのオプションではないようです(少なくとも例によると?)。 。。クライアント(iOS版)の
サーバーのログが(実際の暗号化されていないデータは、単に空のセット[]であることに注意してクライアントに返すために、このようなのJSON表現です
2012-01-04 08:48:13.962
Enter encrypt
D 2012-01-04 08:48:13.962
Input string: []
D 2012-01-04 08:48:13.967
Output encrypted data:[4,254,226,26,101,240,22,113,44,54,209,203,233,64,208,255,]
D 2012-01-04 08:48:13.967
Output encrypted string: BP7iGmXwFnEsNtHL6UDQ/w==
D 2012-01-04 08:48:13.971
Output decrypted back: []
ロギング:
2012-01-04 12:45:13.891 Base64 encoded/Encrypted string: BP7iGmXwFnEsNtHL6UDQ/w==
2012-01-04 12:45:13.892 Encrypted string: <04fee21a 65f01671 2c36d1cb e940d0ff>
2012-01-04 12:45:29.126 Decrypted string:
だから私の質問は以下のとおりです。
- それが「アラインメントエラー」によって何を意味するのか、私が間違って何をやっています?それはクライアントで復号化したくないということですか?
- データの展開を心配する必要はありませんか?もしそうなら、CやObjective-Cのunpack()関数についてどうすればよいでしょうか?
- Google App EngineとiOSの間でAES暗号化を行うより良い方法はありますか?
編集:同じ初期化ベクトルを使用する答えの他に、pythonとパッドのiOSコードの間に矛盾があることがわかりました。暗号化/復号化は少量のデータに対してはうまく機能しましたが、大きなものでは復号化に失敗しました。私は、iOS側をPKCS7Paddingを使用しないように変更し、代わりに0を設定することでこれを修正しました。
暗号化した後、パッキング/エンコードする前にデータのビューをキャプチャし、電話機側でデコードするようにしてください。また、「梱包」とは何を意味するのかを明確にしてください。通常、暗号化されたデータを処理する用語ではありません。 –
私はパッキングと言うとき、私は示されているpythonコードで使用されているstruct.pack()関数を参照しています。 – valheru
これは何ですか? –