3

iOSでkSecPaddingPKCS1を使用してRSA(SecKeyEncrypt)を使用してAESキーを暗号化し、RSAアルゴリズムの標準Javaプロバイダー(javax.crypto)を使用してキーを復号化しようとしています。Javaアプリによって生成された公開鍵を正常に受信し、それをiOSキーチェーンに保存し、それを使用してaesキーを暗号化していますが、Javaアプリで受信すると、よく知られている例外 javax.crypto.BadPaddingException: Data must start が発生しますゼロで。パディングを無効にすると、同じコードが機能します (場合によっては機能します)。では、iOS で使用されるパディングと Java patform で使用されるパディングの違いはどこにあるのでしょうか? 誰かが私に答えを教えてくれますか - 私はこの問題に長い間苦しんでいます。忍耐を失った。

ソースコード。1) 対称鍵を生成し、2) Java アプリからの RSA 公開鍵を使用してラップします。(Tke 公開鍵は、Java アプリによってクライアントに送信されるモジュラスと指数から作成されます) 3) NSData を準備します。暗号化されたキーで初期化し、aes 暗号化データを追加し、Java アプリに送信します。次に、Java アプリは最初の 128 バイト (暗号化された aes キー) を取得して復号化を試み、ここで例外がスローされます。

 [tools generateSymmetricKey];
NSData* encryptedSymetricKey = [tools wrapSymmetricKey:[tools getSymmetricKeyBytes] keyRef:[tools getPeerPublicKeyRef]];
int option = kCCOptionPKCS7Padding;
NSData* aesEncr = [tools doCipher:data key:[tools getSymmetricKeyBytes] context:kCCEncrypt  padding:(CCOptions *)&option];
NSMutableData * result = [[NSMutableData alloc] initWithData:encryptedSymetricKey];
[result appendData:aesEncr];

そして、CryptoExercise から借用したメソッドは、私にとってはうまくいくはずです:

- (NSData *)wrapSymmetricKey:(NSData *)symmetricKey keyRef:(SecKeyRef)publicKey {
OSStatus sanityCheck = noErr;
size_t cipherBufferSize = 0;
size_t keyBufferSize = 0;

LOGGING_FACILITY( symmetricKey != nil, @"Symmetric key parameter is nil." );
LOGGING_FACILITY( publicKey != nil, @"Key parameter is nil." );

NSData * cipher = nil;
uint8_t * cipherBuffer = NULL;

// Calculate the buffer sizes.
cipherBufferSize = SecKeyGetBlockSize(publicKey);
keyBufferSize = [symmetricKey length];

if (kTypeOfWrapPadding == kSecPaddingNone) {
    LOGGING_FACILITY( keyBufferSize <= cipherBufferSize, @"Nonce integer is too large and falls outside multiplicative group." );
} else {
    LOGGING_FACILITY( keyBufferSize <= (cipherBufferSize - 11), @"Nonce integer is too large and falls outside multiplicative group." );
}

// Allocate some buffer space. I don't trust calloc.
cipherBuffer = malloc( cipherBufferSize * sizeof(uint8_t) );
memset((void *)cipherBuffer, 0x0, cipherBufferSize);

// Encrypt using the public key.
sanityCheck = SecKeyEncrypt(    publicKey,
                                kSecPaddingPKCS1,
                                (const uint8_t *)[symmetricKey bytes],
                                keyBufferSize,
                                cipherBuffer,
                                &cipherBufferSize
                            );


LOGGING_FACILITY1( sanityCheck == noErr, @"Error encrypting, OSStatus == %d.", sanityCheck );

// Build up cipher text blob.
cipher = [NSData dataWithBytes:(const void *)cipherBuffer length:(NSUInteger)cipherBufferSize];

if (cipherBuffer) free(cipherBuffer);

return cipher;

}

もう一つ。Java 側では、RSA/ECB/PKCS1Padding 暗号インスタンスを使用しています。

公開鍵の送信方法: Java によって生成された公開鍵はモジュラスと指数に分離され、両方の値が生のバイト配列に変換されて送信されます。次に、ios クライアント側で再生成され、ios キーリング互換の形式に変換されて挿入されます。キーリング。公開鍵は正しく送信されています。両側のモジュラスと公開指数を比較したところ、一致しています。公開鍵も iOS のキーリングに正常にインポートされます (これは BasicEncodingRules BER カテゴリによって達成されます)。PKCS1padding パディング サポートに何か問題があるに違いないと思います - 両方のプラットフォームで異なる必要があります (パディングに関連する計算には、ios で追加のものが必要になる可能性があります)。

4

0 に答える 0