2011-08-23 118 views
4

我想使用AES對Objective-C中的密碼進行加密,然後使用PHP解密,但我遇到了兩個問題。使用AES進行Objective-C加密並使用PHP解密

  1. 我加密密碼,但它是一個NSData對象,所以我用Base64編碼,但是當我在PHP解碼,結果是nil。所以我不能解密它。
  2. 我可以在Objective-C中加密和解密密碼,所以它是PHP的問題,但是當我使用AES進行加密然後使用base64進行編碼時,結果並不相同。

這裏是我的代碼:

PHP:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $key = "a16byteslongkey!"; 
    $plaintext = "iphone"; 
    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_ECB, $iv); 
    $ciphertext = base64_encode($ciphertext); 
    echo "ciphertext: ".$ciphertext."<br/>"; 

    $ciphertext = base64_decode($ciphertext); 
    $plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_ECB, $iv); 
    echo "plaintext: ".$plaintext."<br/>"; 

輸出:

ciphertext: SXNepKfh0IrlDDdkq4EdmQ== 
    plaintext: iphone 

的Objective-C:(此處獲取完整的源代碼:https://gist.github.com/838614

NSString *key = @"a16byteslongkey!"; 
    NSString *plaintext = @"iphone"; 

    NSString *ciphertext = [plaintext AES256EncryptWithKey: key]; 
    NSLog(@"ciphertext: %@", ciphertext); 

    plaintext = [ciphertext AES256DecryptWithKey: key]; 
    NSLog(@"plaintext: %@", plaintext); 

輸出:

ciphertext: D19l3gsgXJlrLl7B2oCT6g== 
    plaintext: iphone 

我kCCKeySizeAES128取代kCCKeySizeAES256,並以「kCCOptionPKCS7Padding取代 「kCCOptionPKCS7Padding」 | kCCOptionECBMode」,

+6

馬上就好像你在PHP中使用128,在Obj-C中使用256 ......這將是一個問題。 –

+0

感謝您的回覆,我用kCCKeySizeAES128替換了kCCKeySizeAES256,並用「kCCOptionPKCS7Padding&kCCOptionECBMode」替換了「kCCOptionPKCS7Padding」,但結果也不一樣。有什麼細節我應該改變? – pcrazyc

+2

你似乎是'base64_encode'在PHP中產生的字符串,但只是將其轉換爲Obj-C中的UTF8。顯然,結果會有所不同。 –

回答

2

我有解決售後服務問題。

  1. 沒有將代碼從https://gist.github.com/838614
  2. 關鍵改變應該是32個字節。
  3. encryt的結果是不一樣的,但如果你解密,他們將是一樣的。

目標c:

NSString *key = @"a16byteslongkey!a16byteslongkey!"; 
NSString *plaintext = @"iphone"; 

NSString *ciphertext = [plaintext AES256EncryptWithKey: key]; 
NSLog(@"ciphertext: %@", ciphertext); 

plaintext = [ciphertext AES256DecryptWithKey: key]; 
NSLog(@"plaintext: %@", plaintext); 

輸出:

ciphertext: I3chV+E2XUHeLCcJAhBaJQ== 
plaintext: iphone 

PHP:

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
$key = 'a16byteslongkey!a16byteslongkey!'; 
$plaintext = "iphone"; 

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_ECB); 
$base64encoded_ciphertext = base64_encode($ciphertext); 
echo "ciphertext: ".$base64encoded_ciphertext."<br/>"; 

$plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($base64encoded_ciphertext), MCRYPT_MODE_ECB); 
echo "plaintext: ".$plaintext."<br/>"; 

$base64encoded_ciphertext = "I3chV+E2XUHeLCcJAhBaJQ=="; 
$plaintext = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($base64encoded_ciphertext), MCRYPT_MODE_ECB); 
echo "plaintext: ".trim($plaintext); 

輸出:

ciphertext: kUr+YsYtb3Uy34li/GPcjg== 
plaintext: iphone 
plaintext: iphone 
+0

嗨,我開始研究一個項目,需要加密iOS上的數據和在運行PHP的服務器上解密它。你能給我詳細的工作嗎? 謝謝! – Shinichi

1

固定使用像

$iv2 = ''; 
    for ($i = 0; $i < 16; $i++) { 
     $iv2 .= "\0"; 
    } 
    mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv2); 
  1. 有些東西不會改變從https://gist.github.com/838614
  2. 代碼中的關鍵應該是32字節
  3. encryt的結果和解密是不一樣的

我試過用這個字符串測試:

$plaintex = "fskfladsadsadfsfs dfskl;dfs a jadfsa ds'a' j afdjdfsaadfs' jdfas af 'ksfegfffffffffffffffffffffsdfsfgfsfdsdfddfsg"

並且結果是不同的。這裏的任何人都知道原因可能是什麼?

0

我懷疑這是填充程序。我已經通過確保將要加密的文本填充爲帶有空格的32個字符並且在解密例程返回結果之前處理這個問題,修剪掉多餘的空格。

有官方的填充算法,但我發現他們沒有工作。如果你加密一個長度爲32個字符的字符串,那麼即使填充程序錯誤,它也會忽略它。

相關問題