2011-01-22 2 views
2

Я пишу некоторые шифрования на C#, которые расшифровываются php. Они не работают вместе очень хорошо. Клиент php сообщил мне об их конфигурации (RSSL_KEYGEN_PKCS5_V20, 256 бит AES в режиме CBC, RSSL_PAD_ANSIX923). Вот что я собрал:Шифрование в .Net-расшифровке в php

public static byte[] Encrypt(byte[] plainText, string password, 
     CipherMode cipherMode, int keySize, PaddingMode paddingMode) 
    { 
     byte[] salt = new byte[8]; 
     new RNGCryptoServiceProvider().GetBytes(salt); 

     // PKCS#5 V2.0 PBKDF2 keyGenerator (uses default iteration count of 1000) 
     Rfc2898DeriveBytes keyGenerator = new Rfc2898DeriveBytes(password, salt); 

     AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); 
     aes.Mode = cipherMode; 
     aes.KeySize = keySize; 
     aes.Padding = paddingMode; 
     aes.Key = keyGenerator.GetBytes(aes.KeySize/8); 

     // aes.Padding is left default PaddingMode.PKCS7 
     // aes.IV should be automatically set to some random value by .NET 
     // (as described in http://msdn.microsoft.com/en-us/library/5e9ft273(VS.71).aspx) 

     // Overestimate encrypted size requirements 
     byte[] encryptedDataBuffer = new byte[plainText.Length + 32 + 32 + 8]; 
     MemoryStream encryptedOutput = new MemoryStream(encryptedDataBuffer, true); 
     CryptoStream encStream = new CryptoStream(encryptedOutput, aes.CreateEncryptor(), 
                CryptoStreamMode.Write); 

     encryptedOutput.Write(salt, 0, salt.Length); 
     encryptedOutput.Write(aes.IV, 0, aes.IV.Length); 
     encStream.Write(plainText, 0, plainText.Length); 

     encStream.FlushFinalBlock(); 
     byte[] encryptedData = new byte[encryptedOutput.Position]; 
     Array.Copy(encryptedDataBuffer, encryptedData, encryptedData.Length); 
     encStream.Close(); 

     return encryptedData; 
    } 

Я могу зашифровать и расшифровать его на моей стороне, но они не могут его расшифровать. Что-то я здесь делаю неправильно? Я проходил примерно так:

Encrypt(mytext, myPassword, CipherMode.CBC, 256, PaddingMode.ANSIX923); 

Спасибо.

+1

Вы уверены, что они используют такое же количество раундов (1000) в генерации ключа? –

+0

Должно быть. Это значение по умолчанию. –

+2

C# и PHP помечены тем же вопросом? это не может быть правдой ... – kelloti

ответ

0

Использование CryptoServiceProvider сделал трюк.

Encoding stringEncoding = new System.Text.UTF8Encoding(); 

     byte[] salt = new byte[8]; 

     new RNGCryptoServiceProvider().GetBytes(salt); 

     AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); 
     aes.Mode = cipherMode; 
     aes.KeySize = keySize; 

     aes.Key = stringEncoding.GetBytes(password); 
     aes.IV = new byte[aes.IV.Length]; 

     // Overestimate encrypted size requirements 
     byte[] encryptedDataBuffer = new byte[plainText.Length + 32 + 32 + 8]; 
     MemoryStream encryptedOutput = new MemoryStream(encryptedDataBuffer, true); 

     CryptoStream encStream = new CryptoStream(encryptedOutput, aes.CreateEncryptor(), 
                CryptoStreamMode.Write); 

     encStream.Write(plainText, 0, plainText.Length); 

     encStream.FlushFinalBlock(); 
     byte[] encryptedData = new byte[encryptedOutput.Position]; 
     Array.Copy(encryptedDataBuffer, encryptedData, encryptedData.Length); 
     encStream.Close(); 

     return encryptedData; 
1

Сначала сузить его: Вы генерируете тот же ключ?

Как только вы уверены в этом, тогда вы можете рассмотреть возможность захвата.

2

Это был вызовом для меня из-за различными способами, что .NET и Mcrypt imlpementations ручки «по умолчанию» AES256. В некоторых версиях PHP m_crypt использует нулевое дополнение, поэтому вам нужно настроить конец .NET, чтобы сделать то же самое:

symbolricKey.Padding = PaddingMode.Zeros;

Я отправил образец PHP & решения C# для GitHub, чтобы помочь другим, которые приходят по одной и той же проблеме: https://github.com/dchymko/.NET--PHP-encryption

Смежные вопросы