2017-07-14 2 views
1

サーバーからアプリケーションに送信されたAES暗号化データの一部を解読しようとしました。Javaを使用して暗号化されたObj-Cを使用してAESデータを解読することができません

問題を解決するために、私はサーバーがやっていることをエミュレートする小さなJavaプログラムを書いています。これは、Base64としてそれをエンコードし、その後AESを使用していくつかのテストデータを暗号化:

AesCipherService cipherService = new AesCipherService(); 
cipherService.setKeySize(128); 

String stringKey = "2EE1F10212ADD4BE"; 
byte[] keyAsBytes = stringKey.getBytes(); 

String text = "text to encrypt"; 
byte[] encryptedBytes = cipherService.encrypt(text.getBytes(), keyAsBytes).getBytes(); 
String base64String  = Base64.encodeToString(encryptedBytes); 
System.out.println(base64String); 

// Reverse the process to check can retrieve "text to encrypt": 
byte[] bytesToDecode = Base64.decode(base64String); 
byte[] decryptedBytes = cipherService.decrypt(bytesToDecode, keyAsBytes).getBytes();   
String decryptedString = new String(decryptedBytes); 
System.out.println(decryptedString); 

実行すると、これが出力されます:

を暗号化する

R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1 + zaIX5A4 =

テキストだから私は正常にデータを暗号化し、それを印刷することができます。暗号化を解除すると元のテキストが表示されるので、ここのすべてがうまくいきます。

ここに私のJavaコードから暗号化されたデータを解読しようとするObj-Cコードがあります。私はOBJ-Cのコンテンツのソースデータを復号化するようNetBeans IDEの出力ウィンドウから暗号化されたデータを貼り付け/コピーした:

- (void) decryptData 
{ 
    NSData* dataToDecrypt  = [[NSData alloc] initWithBase64EncodedString: @"R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1+zaIX5A4=" options: 0]; 
    NSString* key    = @"2EE1F10212ADD4BE"; 

    char keyPtr[kCCKeySizeAES128]; 
    bzero(keyPtr, sizeof(keyPtr)); 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [dataToDecrypt length]; 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesDecrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, 
              kCCAlgorithmAES, 
              kCCOptionPKCS7Padding, 
              keyPtr, 
              kCCBlockSizeAES128, 
              keyPtr, 
              [dataToDecrypt bytes], 
              dataLength, 
              buffer, 
              bufferSize, 
              &numBytesDecrypted); 
    if (cryptStatus == kCCSuccess) { 
     NSLog(@"Success"); 
     NSData* unencryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
     Byte *unencryptedAsBytes = (Byte*)malloc(unencryptedData.length); 
     memcpy(unencryptedAsBytes, [unencryptedData bytes], unencryptedData.length); 
     NSString *decryptedString = [NSString stringWithUTF8String:[unencryptedData bytes]]; 
     NSLog(@"%@", decryptedString); 
    } 
} 

これを実行すると、ステータスがkCCSuccessで、numBytesDecryptedは32である(同じ"暗号化したテキスト" ではありませんDATALENGTHとして)が、復号化された文字列、decryptedStringはnilであるとXcodeのコンソールでのI、経口unencryptedAsBytes場合には、この表示されます「

を\さaY | 376 \ 347cD * \ 320NC \ X14 \ \ x91C \ x88 \ 301 \ 341z \ xaca \ x11 \ 371

任意ここで何が問題なのか?

+0

4. W進で

ここに 'AesCipherService'が文書化されていますか? IVとして鍵を使用していますか?安全ではありません。 5.おそらくtheIVは、暗号化されたデータの最初の16バイトです。これは珍しいことではありません。 – zaph

+0

@zaph AesCipherServiceは、Apache暗号ライブラリhttps://shiro.apache.org/static/1.2.3/apidocs/org/apache/shiro/crypto/AesCipherService.htmlの一部です。コードのJava部分は私が書いたものではなく、サーバー開発者が書いています。Objective-Cの部分を書いて暗号化したものを解読しようとしています。私が上に投稿したコードは、より管理しやすい方法で問題を再作成しようとすると、凝縮した形式で行ったことを再作成することです。彼らは上記のようにAesCipherServiceを使用しています。つまり、IVなどを明示的に設定していないため、AesCipherServiceのデフォルトが使用されています。 – Gruntcakes

答えて

2

Java暗号化コードは、ランダムIVを生成し、暗号化されたものに接頭辞を付けます。解読するために、IVは暗号化されたものから分割される。

key:  32454531463130323132414444344245 
iv:  479501A4FDF46235FD01ED87A0F6F646 (first 16 binary bytes of the full encryption) 
encrypted: B7E2E6B40963677469CD7ECDA217E40E (rest of binary bytes of the full encryption) 
decrypted: 7465787420746F20656E6372797074 

コード:

NSData* fullEncrypted  = [[NSData alloc] initWithBase64EncodedString: @"R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1+zaIX5A4=" options: 0]; 
NSData *ivData = [fullEncrypted subdataWithRange:NSMakeRange(0, kCCBlockSizeAES128)]; 
NSData *encryptedData = [fullEncrypted subdataWithRange:NSMakeRange(kCCBlockSizeAES128, fullEncrypted.length-kCCBlockSizeAES128)]; 
NSLog(@"ivData:   %@", ivData); 
NSLog(@"encryptedData: %@", encryptedData); 

NSData *keyData = [@"2EE1F10212ADD4BE" dataUsingEncoding:NSUTF8StringEncoding]; 
NSLog(@"keyData:   %@", keyData); 

NSMutableData *unencryptedData = [NSMutableData dataWithLength:encryptedData.length]; 
size_t numBytesDecrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, 
             kCCAlgorithmAES, 
             kCCOptionPKCS7Padding, 
             keyData.bytes, keyData.length, 
             ivData.bytes, 
             encryptedData.bytes, encryptedData.length, 
             unencryptedData.mutableBytes, unencryptedData.length, 
             &numBytesDecrypted); 
if (cryptStatus == kCCSuccess) { 
    NSLog(@"Success"); 

    unencryptedData.length = numBytesDecrypted; 
    NSLog(@"unencryptedData: %@", unencryptedData); 

    NSString *decryptedString = [[NSString alloc] initWithData:unencryptedData encoding:NSUTF8StringEncoding]; 
    NSLog(@"decryptedString: %@", decryptedString); 
} 

出力:

ivData:   479501a4 fdf46235 fd01ed87 a0f6f646 
encryptedData: b7e2e6b4 09636774 69cd7ecd a217e40e 
keyData:   32454531 46313032 31324144 44344245 
Success 
unencryptedData: 74657874 20746f20 656e6372 79707400 
decryptedString: text to encrypt 
+0

本当に素晴らしい!ありがとうございます、私は文字通り数日間これに固執してきました。ランダムIVが暗号化されたデータの前に追加されていたとはどのように判断しましたか? – Gruntcakes

+0

これは一般的なことであり、暗号化されたデータは1ブロック長くなるはずです。また、ObjCコードはデフォルトでCBCモードになり、IVが必要でした。もちろん私は間違っていたエンコーディングについて最初に推測しました。 zaph

+0

ところで、ここでこと、出力データの末尾01に注意し、ニート[AESコンバータ(http://extranet.cryptomathic.com/aescalc?key=32454531463130323132414444344245&iv=479501A4FDF46235FD01ED87A0F6F646&input=B7E2E6B40963677469CD7ECDA217E40E&mode=cbc&action=Decrypt&output=B47CF26CD2992D0A765D1731AB4B2904)でありますパディングです。 – zaph

関連する問題