1

使用 PHP 5.4 (mcrypt)、RNCryptor 2、iOS 6。

PHP 函数使用https://github.com/rnapier/RNCryptor/wiki/Data-Format中引用的所有标头创建 base64 。

PHP 解密函数可以解密来自 RNEncryptor 的 base64 字符串,下面的 PHP 加密函数按预期返回数据。

在下面的 PHP Encrypt 函数中使用带有 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 不匹配错误

数据=(空),错误域=net.robnapier.RNCryptManager 代码=1“HMAC 不匹配”用户信息=0x1e564280 {NSLocalizedDescription=HMAC 不匹配}

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/PHP kCCDecodeError 以了解其他实现。

最后,从RNCryptor Wiki Data Format 中,我看到了(连同Stack Overflow 上 PHP 实现的链接)

HMAC 是使用密文和 HMACKey(上图)和 SHA-256 PRF 生成的。

...但是您附加的 HMAC 在我看来实际上是 HMACKey,而不是 HMAC ...?

于 2013-01-09T23:07:18.260 回答
0

问题是由于不正确的 HMAC(正在传递 HMAC 密钥)和 PHP 加密需要对要加密的数据进行 PKCS7 填充(也不是 IV)。

最终的 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 回答