我有AES加密/解密的問題。評論的代碼工作,但有時給錯誤「填充是無效的,不能被刪除」,所以我改變它,因爲它在這裏解釋Padding is invalid and cannot be removed Exception while decrypting string using "AesManaged" C#Aes解密器給出空字符串
但是當我嘗試它下面的代碼在解密時給出一個空字符串。我不知道我在哪裏犯錯。兩個靜態函數bytesToString和stringToBytes與加密無關,我在其他地方使用它們。密鑰長度和塊大小是OKAY。 我發現這個在debbuger:
「 'csEncrypt.Length' 扔 'System.NotSupportedException' 類型的異常」
我在.NET 3.5的Visual Studio 2008
在這裏工作是調試prtscr如u可以在離開塊加密爲0字節長的CryptoStream有一些例外
如何修復後看到了什麼?請給我一些線索。
static class Aes
{
public static string bytesToHexString(byte[] key)
{
return BitConverter.ToString(key).Replace("-", String.Empty);
}
public static byte[] stringToBytes(string key)
{
return Enumerable.Range(0, key.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(key.Substring(x, 2), 16))
.ToArray();
}
public static void generateKeyAndIv(out byte[] key, out byte[] IV)
{
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
aesAlg.Padding = PaddingMode.None;
//aesAlg.Mode = CipherMode.CBC;
aesAlg.GenerateKey();
aesAlg.GenerateIV();
key = aesAlg.Key;
IV = aesAlg.IV;
}
}
public static string EncryptStringToString(string plainText, byte[] Key, byte[] IV)
{
byte[] bytes =EncryptStringToBytes_Aes(plainText, Key, IV);
return Convert.ToBase64String(bytes);
//return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
public static string DecryptStringToString(string cipherText, byte[] Key, byte[] IV)
{
//byte[] bytes = Encoding.UTF8.GetBytes(cipherText);
byte[] bytes = Convert.FromBase64String(cipherText);
return DecryptStringFromBytes_Aes(bytes, Key, IV);
}
public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
/*byte[] encrypted;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
}
encrypted = msEncrypt.ToArray();
}
}*/
byte[] encrypted;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
// Create a decrytor to perform the stream transform.
aesAlg.Padding = PaddingMode.None;
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
}
//return encrypted;
// Return the encrypted bytes from the memory stream.
return encrypted;
}
public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an AesCryptoServiceProvider object
// with the specified key and IV.
using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
{
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
好的,也許我會解釋一下整個情況。我寫了自己的安全電子郵件。我有兩次加密。服務器和客戶端之間的通信由RSA和AES加密。用戶創建的消息也由RSA + AES加密。
發送的消息是這樣的:
- 客戶端連接到服務器。
- 建立安全連接(服務器發送公鑰,客戶端生成AES密鑰,通過服務器的公鑰加密後發送給服務器,服務器和客戶端使用AES密鑰進行通信後)。
- 客戶端使用XML創建消息,消息可以包含讀取到base64的文件,之後使用AES加密。
- 該消息被寫入數據庫。
recieving消息是這樣的:
- 連接到服務器。
- 建立安全連接。
- 從服務器獲取消息。
- 使用RSA私鑰解密AES密鑰。
- 使用解密的AES密鑰解密消息。
- 如果有文件,然後使用AES解密它們,並將它們解碼爲字節並保存。
現在的問題是加密大數據。即使200-300 kB也有問題。
我發現的另一個有趣的事情是,當我通過調試器運行代碼時,它可以工作,但是當我沒有它運行代碼時。它不起作用。
解決方案
我發現的問題的解決方案。因爲我使用不同的密鑰/ iv來非常快速地使用AES加密/解密兩次垃圾收集器沒有清除這些對象。剛剛返回由DecryptStringFromBytes_Aes和EncryptStringToBytes_Aes
我希望這會幫助誰是有同樣的問題,就像我有某人前值溶液中加入
GC.Collect();
GC.WaitForPendingFinalizers();
。
它會爲你,如果你整理您的實現一點發現問題更容易。 – 2013-03-01 08:32:11
現在我試圖從這裏使用http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged.aspx代碼,並且此代碼給我「填充無效」異常。因此,當我使用來自MSDN的示例代碼時,我有一個空字符串或有時會出現「填充無效異常」。 – Robert 2013-03-01 08:34:14
我發現msdn中的代碼在需要大量數據解密/加密的情況下無法使用。 – Robert 2013-03-01 08:52:35