1

PHP 5.4(mcrypt)、RNCryptor 2、iOS6を使用します。

PHP関数は、https://github.com/rnapier/RNCryptor/wiki/Data-Formatから参照されるように、すべてのヘッダーを含むbase64を作成します。

RNEncryptorと以下のPHPEncrypt関数の両方からbase64文字列を復号化できるPHP復号化関数は、期待どおりにデータを返します。

以下のPHP暗号化関数のbase64でRNDecryptorを使用すると、以下のXCode出力に示すようにデータは返されません。

PHP関数:

function encrypt($data, $key)
{
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

    $salt = '12345678';

    $_key = $this->pbkdf2('SHA1', $key, $salt, 10000, 32, true);

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $_key, $data, MCRYPT_MODE_CBC, $iv);

    $hmac = $this->pbkdf2('SHA1', $key, $salt, 10000, 32, true);

    $data = mb_convert_encoding(chr(1).chr(0).$salt.$salt.$iv.$ciphertext.$hmac, "BASE64", "UTF-8");

    return $data;
}

PHP関数呼び出し:

encrypt('My Data', 'mykey');

iOS:

NSError * error;
NSData *decryptedData = [RNDecryptor decryptData:[NSString base64DataFromString:@"AQBpcGhvbmU2MmlwaG9uZTYyrYk2rJnaoywktnx6TZ4X3YKgYuEHCL1EHv+/MqIvQMq5BmZOyMJr QSRs9P4uxShsOJOg67VYniUGhHbFNTSl1Q=="]
                                    withPassword:@"mykey"
                                           error:&error];

NSLog(@"data = %@, %@", decryptedData, error);

XCode出力:

データ=<>、(null)

これは、RNDecryptor -finishでHMAC検証をコメントアウトするときに実行されます。これらのセクションのコメントが解除されると、HMAC不一致エラーが発生します。

data =(null)、Error Domain = net.robnapier.RNCryptManager Code = 1 "HMAC Mismatch" UserInfo = 0x1e564280 {NSLocalizedDescription = HMAC Mismatch}

if (self.hasHMAC) {
  NSMutableData *HMACData = [NSMutableData dataWithLength:self.HMACLength];
  CCHmacFinal(&_HMACContext, [HMACData mutableBytes]);

  if (![HMACData isEqualToData:self.inData]) {
    [self cleanupAndNotifyWithError:[NSError errorWithDomain:kRNCryptorErrorDomain
                                                        code:kRNCryptorHMACMismatch
                                                    userInfo:[NSDictionary dictionaryWithObject:@"HMAC Mismatch"
                                                                                         forKey:NSLocalizedDescriptionKey]]];
    return;
  }
}
4

2 に答える 2

2

mb_convert_encoding()base64変換を実行しますが、チャンク化されたbase64を出力します。

PHP base64デコーダーは、チャンクとアンチャンクの両方を受け入れますが、iOS ...?

おそらく、エンコードする必要があります。

$data = base64_encode(chr(1).chr(0).$salt.$salt.$iv.$ciphertext.$hmac);

別の実装については、iOS /PHPkCCDecodeErrorを確認することをお勧めします。

最後に、RNCryptor Wiki Data Formatから、( Stack OverflowでのPHP実装へのリンクとともに)がわかります。

HMACは、暗号文とHMACKey(上記)およびSHA-256PRFを使用して生成されます。

...しかし、追加するHMACは、実際にはHMACではなくHMACKeyであるように見えます...?

于 2013-01-09T23:07:18.260 に答える
0

この問題は、誤ったHMAC(HMACキーを渡していた)とPHP暗号化の両方が原因で、暗号化するデータ(IVでもない)にPKCS7パディングが必要でした。

最終的なPHP関数...

function AES256Encrypt($data, $key)
{
    $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $pad = $block - (strlen($data) % $block);
    $data .= str_repeat(chr($pad), $pad);

    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

    $keySalt = '12345678';
    $hmacSalt = '12345678';

    $_key = $this->pbkdf2('SHA1', $key, $keySalt, 10000, 32, true);
    $_hmacKey = $this->pbkdf2('SHA1', $key, $hmacSalt, 10000, 32, true);

    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $_key, $data, MCRYPT_MODE_CBC, $iv);

    $data = base64_encode(chr(1).chr(0).$keySalt.$hmacSalt.$iv.$ciphertext.hash_hmac('SHA256',$ciphertext,$_hmacKey, true));
    return $data;
}
于 2013-01-10T00:37:49.823 に答える