2013-01-09 121 views
1

使用PHP 5.4(mcrypt的),RNCryptor 2的iOS 6.PHP AES256加密=> RNCryptor RNDecryptor返回空白/ HMAC不匹配

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

PHP解密函数,它可以解密来自RNEncryptor和PHP Encrypt函数的base64字符串,并按照预期返回数据。

从下面的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输出:

数据= <>,(空)

这样做是当我注释掉HMAC验证在RNDecryptor - 完成,一旦这些部分未被注释我接收HMAC不匹配错误

数据=(空),错误域= net.robnapier.RNCryptManager代码= 1 “HMAC不匹配” 的UserInfo = 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; 
    } 
} 
+0

AFAIK:mb_convert_encoding用于不同字符集之间的转换。 BASE64不是一个字符集。它是一种传输编码。你知道base64_decode()吗?试试它而不是mb_convert_encoding。 – hek2mgl

+0

在PHP端更改为base64_encode(),并且仍然从RNDecryptor iOS端获得HMAC不匹配。 –

+0

'var_dump($ salt,$ iv,$ ciphertext,$ hmac);'说什么? – hek2mgl

回答

0

该问题是由于HMAC(正在传递HMAC密钥)和需要PKCS7填充的PHP加密(不是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; 
} 
+0

你能否粘贴最新的IOS代码 – Saeed

+0

它只是使用标准的[RNCryptor](https://github.com/rnapier/RNCryptor)库。 –

+0

我知道,但我在询问你传递给这个图书馆的参数 .. 提前感谢你 – Saeed

2

mb_convert_encoding()将d o base64转换,但它会输出chunked base64。

PHP base64解码器将接受chunked和unchunked,但iOS ...?

也许你只是需要编码:

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

您可能需要为另一个实现退房iOS/PHP kCCDecodeError

最后,从RNCryptor Wiki数据格式,我看到(具有链接在一起以the PHP implementation on Stack Overflow

HMAC利用密文和所述HMACKey(上图)和SHA-256 PRF产生。你追加

...但HMAC在我看来,其实是HMACKey,而不是HMAC ...?

+0

正如我回答hek2mgl,我改为base64_encode(),仍然得到HMAC不匹配。 “descryptData:”中的空格来自PHP的base64输出 –

+0

我没有得到它 - 从字面上看:我的输出没有这个空间从命令行使用PHP 5.3.15进行测试尝试用手去除空间, – LSerni

+0

“_如果使用base64_encode(),base64输出与使用mb_convert_encoding()时相比会有所不同 - ”“是的,mb_convert_encoding()增加了一个空格,引用的可可片段是mb_convert_encoding()此后我输入了base64_encode()字符串,仍然出现HMAC错误s。 –