2010-02-11 62 views
6

我解密使用PHP數據與此代碼:不能解密與使用PHP加密C#數據(Rijdael-128)

$content="1234"; 
$cp = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
$iv = mcrypt_create_iv(16, MCRYPT_RAND); 
$key = pack("H*",md5('a')); 
mcrypt_generic_init($cp, $key, $iv); 
$encrypted = mcrypt_generic($cp, $content); 
echo base64_encode($key)."\n"; 
echo base64_encode($iv)."\n"; 
echo base64_encode($encrypted)."\n"; 
mcrypt_generic_deinit($cp); 
mcrypt_module_close($cp); 

$ IV和$加密,然後保存到文件和C#樣品中的讀應用:

var iv=...; 
var encrypted=...; 
var md5 = new MD5CryptoServiceProvider(); 
var key = md5.ComputeHash(Encoding.Default.GetBytes("a")); 
md5.Clear(); 

Console.WriteLine(Convert.ToBase64String(key)); 
Console.WriteLine(Convert.ToBase64String(iv)); 
Console.WriteLine(Convert.ToBase64String(encrypted)); 

這裏的輸出是完全一樣從PHP的輸出,所以我可以保證沒有編碼錯誤其間。

var rd = new RijndaelManaged { 
    Key = key, 
    IV = iv, 
    Mode = CipherMode.CBC, 
    KeySize = 128, 
    Padding = PaddingMode.Zeros 
}; 

var buffer = new byte[encrypted.Length]; 
using(var ms = new MemoryStream(buffer)) { 
    using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Write)) { 
    cs.Write(encrypted, 0, encrypted.Length); 
    ms.Read(buffer, 0, buffer.Length); 
    Console.WriteLine(Encoding.Default.GetString(buffer)); 
    } 
} 
rd.Clear(); 

解密的結果對每一個程序開始變化,甚至完全一樣的輸入數據:

首先運行:
DMF1ucDxtqgxw5niaXcmYQ == < -Key
GoCeRkrL/EMKNH/BYeLsqQ == < -IV
UBE3DkgbJgj1K/TISugLxA == < -Encrypted
OlOB99yiCYRDoLx + 0xxZxQ == < - 「解密的」

第二輪:
DMF1ucDxtqgxw5niaXcmYQ == < -Key
GoCeRkrL/EMKNH/BYeLsqQ == < -IV
UBE3DkgbJgj1K/TISugLxA == < -Encrypted
w5fcY5Fbb9KRgoHfhqAztA == < - 「解密的」

關鍵,IV,加密的數據是相同的,但是解密日期仍然不同,並且總是錯誤的。緩衝區應該包含「1234」或「1234」加上12個尾隨零。

我不明白爲什麼結果各不相同的,什麼是不工作的,但我一直在這個該死的一塊好幾個小時的代碼現在盯着,而且很可能錯過了明顯的錯誤...

逆轉像這樣的CryptoStream會產生相同的錯誤結果:

using(var ms = new MemoryStream(encrypted)) { 
    using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) { 
    cs.Read(buffer, 0, buffer.Length); 
    Console.WriteLine(Convert.ToBase64String(buffer)); 
    } 
} 

幫助? 謝謝! 亞歷山大

回答

5

好,修改我過去的罪惡的舊樣品我結束了與此:

static string Decrypt() {    
    byte[] keyBytes = Convert.FromBase64String("DMF1ucDxtqgxw5niaXcmYQ=="); 
    byte[] iv = Convert.FromBase64String("GoCeRkrL/EMKNH/BYeLsqQ=="); 
    byte[] cipherTextBytes = Convert.FromBase64String("UBE3DkgbJgj1K/TISugLxA=="); 

    var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC, IV = iv, KeySize = 128, Key = keyBytes, Padding = PaddingMode.Zeros}; 

    using (var decryptor = symmetricKey.CreateDecryptor()) 
    using (var ms = new MemoryStream(cipherTextBytes)) 
    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { 
    var plainTextBytes = new byte[cipherTextBytes.Length]; 
    int decryptedByteCount = cs.Read(plainTextBytes, 0, plainTextBytes.Length); 
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
    } 
} 

這給了「1234」尾隨\ 0字符..你剛纔忘了轉換byte []再次轉換爲字符串?我錯過了什麼其他區別?

+0

該解決方案非常簡單,但大多煩人......您必須在設置「Key」屬性之前設置「KeySize」屬性*。 我將代碼逐步轉換爲符合您的代碼,只要我切換了兩個設置器,它就可以工作。 如果有人來自Microsoft正在偵聽,您可能會將這一點信息包含到MSDN中。我知道這一點很明顯,一旦你知道它,但... 本傑明,丹科! – 2010-02-12 08:14:03