2015-05-27 66 views
0

我試圖使用AES對一個字符串進行編碼和解碼。目前,我使用最高等級的答案here對Mono C#中的字符串進行編碼,因爲System.Security.Crytpography.Aes在Mono中不可用。然而,這個實現使用了一個Salt,並且我用來解密它的PHP method不需要鹽,只有一個初始化向量,我生成了。在C#和PHP中使用AES加密AES

我的問題:加密的數據是鹽漬的,我不知道如何用已知鹽串解鹽。

  1. 我應該嘗試從C#類中除去鹽嗎?
    • 僅使用純文本,密碼/密鑰和初始化向量,實現是否足夠好?
  2. 或者還有另一種形式的解密,我可以在PHP中使用,將採取密文,密鑰,鹽和初始化向量?
  3. 或者我應該嘗試在調用mcrypt_decrypt之後解除解密的文本?這是事物的正確順序嗎?
  4. 或者我應該完全重寫C#AES類嗎?這實際上是一個不好的例子嗎?
  5. [編輯]或者是否有人知道我可以在PHP中使用Rfc2898DeriveBytes實現?我不確定自己有足夠的信心自己寫實現,以免因爲某種錯誤而徹底擊敗安全點。

對不起,我的無知,這是第一次,我曾經處理了加密,並有大量的信息採取英寸

+1

這是不可能的東西。您必須在PHP中重新創建相同的密鑰派生代碼。提示:這可能是PBKDF2。您必須問自己,您是需要基於密碼的解決方案還是基於密鑰的解決方案。 –

+0

因此,在仔細閱讀代碼後,我需要做的是從原密碼/密鑰和鹽中派生出一組新字節用作解密密鑰?我有這個權利嗎?這意味着我仍然需要在PHP中實現'Rfc2898DeriveBytes',如@ Ospho的答案中所述,我假設? – Arcandio

回答

2

答案you have posted實現Rfc2898DeriveBytes類得到的字節加密密鑰。 This is advised, but not mandatory。您不必使用Rfc2898DeriveBytes,並且可以簡單地修改該AES實現,不要冒險,只需將密碼的字節直接作爲密鑰。雖然我不建議在實踐中這樣做。

我建議的是找到一個更適合的PHP AES實現,它允許你的密碼被醃製以獲得關鍵字節 - 應該可用(對不起,但我沒有什麼PHP經驗幫助你;你可能會發現在PHP加密庫中存在一個額外的方法來基於類似於.NET/MONO的Rfc2898DeriveBytes)密碼和鹽輸入形成密鑰。

+0

我想幫忙。 Rfc2898Derive是否使用sha1對salt進行1000次迭代?我會發布一些PHP代碼,但我沒有辦法測試它給出了正確的結果,我無法找到一個在線實現來測試。有沒有測試數據? – Phil

+0

我最終用了phpseclib,它效果很好。謝謝您的幫助。 – Arcandio

0

#1號

#2是(見下文)

#3沒有

#4沒有,它看起來好像沒什麼問題

#5,請試試這個用PHP實現你的加密數據。我沒有測試過它。

<?php 

function pbkdf2($p, $s, $c, $kl, $a = 'sha1') { 
    $hl = strlen(hash($a, null, true)); # Hash length 
    $kb = ceil($kl/$hl);    # Key blocks to compute 
    $dk = '';       # Derived key 
    # Create key 
    for ($block = 1; $block <= $kb; $block ++) { 
     # Initial hash for this block 
     $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true); 
     # Perform block iterations 
     for ($i = 1; $i < $c; $i ++) 
      # XOR each iterate 
      $ib ^= ($b = hash_hmac($a, $b, $p, true)); 
     $dk .= $ib; # Append iterated block 
    } 
    # Return derived key of correct length 
    return substr($dk, 0, $kl); 
} 

//Usage example (Decryption by PHP) 
$ciphertext_b64 = "owiCMbopBmr+NvjBEUT2Hg=="; 

$password = "password"; 
$salt = "g46dzQ80"; //Please change to the salt you are using. Copied from the referenced answer code. 

//This is the key derivation part. I think .net uses 1000 iterations of sha1. 
$key = pbkdf2($password, $salt, 1000, 32, "sha1"); 
$iv = "OFRna74m*aze01xY"; //Again, I copied the IV from the .NET code in the answer you referenced. 

$plaintext = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($ciphertext_b64), MCRYPT_MODE_CBC, $iv), "\0"); 

echo $plaintext; 
// Output = hello