2013-01-09 151 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。 –