6

Android に AES128 暗号化を実装しようとしています。Objective C を搭載した iPhone で動作するソリューションがありますが、Android への移植に問題があります。解決策をstackoverflowで検索しましたが、何か間違っているようです。私はJavaにかなり慣れていないので、データ、文字列変換に関係する何かが欠けていると思います。

これが私のiPhoneの暗号化です:

char keyPtr[kCCKeySizeAES128+1];
[keyString getCString:keyPtr
            maxLength:sizeof(keyPtr)
             encoding:NSASCIIStringEncoding];

// CString for the plain text
char plainBytes[[plainString length]+1];
[plainString getCString:plainBytes
              maxLength:sizeof(plainBytes)
               encoding:NSASCIIStringEncoding];

size_t bytesEncrypted = 0;

// Allocate the space for encrypted data
NSUInteger dataLength = [plainString length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);

// Encrypt
CCCryptorStatus ret = CCCrypt(kCCEncrypt,
                              kCCAlgorithmAES128,
                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                              keyPtr,
                              kCCKeySizeAES128,
                              NULL,
                              plainBytes, sizeof(plainBytes),
                              buffer, bufferSize,
                              &bytesEncrypted);
if (ret != kCCSuccess) {
    free(buffer);
}

encryptedData = [NSData dataWithBytes:buffer length:bytesEncrypted];

これが私のJavaです:

    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));

iPhone と Java で同じキーと平文を使用すると、異なる結果が得られます。私のiPhoneの結果は必要な方法で機能するので、iPhoneの結果を得るためにJavaを取得しようとしています。私は確かにJavaに何かが欠けています。それが何であるかはわかりません。

編集

以下の提案に基づいて、Javaをこれに変更しました

    byte[] keyBytes = plainTextKey.getBytes("US-ASCII");
    SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(plainText.getBytes("US-ASCII"));

しかし、私はまだAndroidとiPhoneの間で異なる結果を得ています

4

3 に答える 3

4

プレーンテキストでのエンコードの問題に加えて (コメントで vcsjones が指摘したように)、キー文字列のエンコードが同じであることを確認してください (パスワードのような生の文字列を暗号キーとして直接使用することは悪いニュースです)。ベア、パスワードで PBKDF2 のようなキー派生関数を使用してキーを派生させます)。

また、ASCII 用の Java のエンコーディング文字列はUS-ASCIIだけでなくであるため、呼び出しASCIIでは必ずそれを使用してください。getBytes

EDIT : 問題が見つかりました: iOS 文字列は最後に余分なヌル文字 (0x00) で暗号化されていますが、Java はそうではありませんでした。したがって、Java で「hello world\0」を暗号化すると、iOS で「hello world」と同じ出力が得られます。

于 2013-03-13T17:07:21.503 に答える
0

インターネット上のほとんどの例は、AES の弱い実装です。実装が強力であるためには、ランダム IV を常に使用し、キーをハッシュする必要があります。

より安全な(ランダム IV + ハッシュ キー)クロス プラットフォーム(android、ios、c#)の AES 実装については、こちらの回答を参照してください - https://stackoverflow.com/a/24561148/2480840

于 2014-07-03T19:04:00.390 に答える