C# Aes解密程序给出空字符串
我对AES加密/解密有问题。注释后的代码工作正常,但有时会出现错误“padding无效且无法删除”,因此我按照此处的说明对其进行了更改 但是当我尝试它时,下面的代码在解密过程中给出了一个空字符串。我不知道我在哪里犯了错误。TestOstring和stringToBytes的两个静态函数与加密无关,我在其他地方使用它们。关键帧长度和块大小都可以。 我在debbuger中发现了这个: “'csEncrypt.Length'引发了类型为'System.NotSupportedException'的异常” 我在3.5.NETVisualStudio2008上工作 这是调试器中的prtscr,正如您在离开加密块后看到的,加密块的长度为0字节,加密流有一些异常 如何修复它?请给我一些线索C# Aes解密程序给出空字符串,c#,.net,cryptography,aes,rijndaelmanaged,C#,.net,Cryptography,Aes,Rijndaelmanaged,我对AES加密/解密有问题。注释后的代码工作正常,但有时会出现错误“padding无效且无法删除”,因此我按照此处的说明对其进行了更改 但是当我尝试它时,下面的代码在解密过程中给出了一个空字符串。我不知道我在哪里犯了错误。TestOstring和stringToBytes的两个静态函数与加密无关,我在其他地方使用它们。关键帧长度和块大小都可以。 我在debbuger中发现了这个: “'csEncrypt.Length'引发了类型为'System.NotSupportedException'的异常
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;
}
}
在通过DecryptStringFromBytes_Aes和EncryptStringToBytes_Aes返回值之前
我希望它能帮助像我一样有同样问题的人。您使用流的方式意味着没有数据被写入底层流,我不知道为什么,但我确实找到了另一种方法,我已经修改了 使用以下代码,您应该能够作为控制台应用程序运行,然后对其进行重塑,使其符合您的目的。让我知道进展如何:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Encrypto
{
public static class Program
{
public static void Main()
{
const string password = "test";
const string text = "test";
var cipherText = Aes.Encrypt(password, text);
var decrypted = Aes.Decrypt(password, cipherText);
Console.WriteLine(decrypted);
Console.ReadKey();
}
}
internal static class Aes
{
public static EncryptedData Encrypt(string password, string data)
{
return Transform(true, password, data, null) as EncryptedData;
}
public static string Decrypt(string password, EncryptedData data)
{
return Transform(false, password, data.DataString, data.SaltString) as string;
}
private static object Transform(bool encrypt, string password, string data, string saltString)
{
using (var aes = new AesManaged())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
var keyLen = aes.KeySize/8;
var ivLen = aes.BlockSize/8;
const int saltSize = 8;
const int iterations = 8192;
var salt = encrypt ? new byte[saltSize] : Convert.FromBase64String(saltString);
if (encrypt)
{
new RNGCryptoServiceProvider().GetBytes(salt);
}
var bcKey = new Rfc2898DeriveBytes("BLK" + password, salt, iterations).GetBytes(keyLen);
var iv = new Rfc2898DeriveBytes("IV" + password, salt, iterations).GetBytes(ivLen);
var macKey = new Rfc2898DeriveBytes("MAC" + password, salt, iterations).GetBytes(16);
aes.Key = bcKey;
aes.IV = iv;
var rawData = encrypt ? Encoding.UTF8.GetBytes(data) : Convert.FromBase64String(data);
using (var transform = encrypt ? aes.CreateEncryptor() : aes.CreateDecryptor())
using (var memoryStream = encrypt ? new MemoryStream() : new MemoryStream(rawData))
using (var cryptoStream = new CryptoStream(memoryStream, transform, encrypt ? CryptoStreamMode.Write : CryptoStreamMode.Read))
{
if (encrypt)
{
cryptoStream.Write(rawData, 0, rawData.Length);
cryptoStream.FlushFinalBlock();
return new EncryptedData(salt, macKey, memoryStream.ToArray());
}
var originalData = new byte[rawData.Length];
var count = cryptoStream.Read(originalData, 0, originalData.Length);
return Encoding.UTF8.GetString(originalData, 0, count);
}
}
}
public class EncryptedData
{
public EncryptedData(byte[] salt, byte[] mac, byte[] data)
{
Salt = salt;
MAC = mac;
Data = data;
}
private byte[] Salt { get; set; }
public string SaltString
{
get { return Convert.ToBase64String(Salt); }
}
private byte[] MAC { get; set; }
private byte[] Data { get; set; }
public string DataString
{
get { return Convert.ToBase64String(Data); }
}
}
}
}
提供此答案的来源:您使用流的方式意味着没有数据被写入底层流,我不知道为什么,但我确实找到了一种我已经修改过的替代方法 使用以下代码,您应该能够作为控制台应用程序运行,然后对其进行重塑,使其符合您的目的。让我知道进展如何:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Encrypto
{
public static class Program
{
public static void Main()
{
const string password = "test";
const string text = "test";
var cipherText = Aes.Encrypt(password, text);
var decrypted = Aes.Decrypt(password, cipherText);
Console.WriteLine(decrypted);
Console.ReadKey();
}
}
internal static class Aes
{
public static EncryptedData Encrypt(string password, string data)
{
return Transform(true, password, data, null) as EncryptedData;
}
public static string Decrypt(string password, EncryptedData data)
{
return Transform(false, password, data.DataString, data.SaltString) as string;
}
private static object Transform(bool encrypt, string password, string data, string saltString)
{
using (var aes = new AesManaged())
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
var keyLen = aes.KeySize/8;
var ivLen = aes.BlockSize/8;
const int saltSize = 8;
const int iterations = 8192;
var salt = encrypt ? new byte[saltSize] : Convert.FromBase64String(saltString);
if (encrypt)
{
new RNGCryptoServiceProvider().GetBytes(salt);
}
var bcKey = new Rfc2898DeriveBytes("BLK" + password, salt, iterations).GetBytes(keyLen);
var iv = new Rfc2898DeriveBytes("IV" + password, salt, iterations).GetBytes(ivLen);
var macKey = new Rfc2898DeriveBytes("MAC" + password, salt, iterations).GetBytes(16);
aes.Key = bcKey;
aes.IV = iv;
var rawData = encrypt ? Encoding.UTF8.GetBytes(data) : Convert.FromBase64String(data);
using (var transform = encrypt ? aes.CreateEncryptor() : aes.CreateDecryptor())
using (var memoryStream = encrypt ? new MemoryStream() : new MemoryStream(rawData))
using (var cryptoStream = new CryptoStream(memoryStream, transform, encrypt ? CryptoStreamMode.Write : CryptoStreamMode.Read))
{
if (encrypt)
{
cryptoStream.Write(rawData, 0, rawData.Length);
cryptoStream.FlushFinalBlock();
return new EncryptedData(salt, macKey, memoryStream.ToArray());
}
var originalData = new byte[rawData.Length];
var count = cryptoStream.Read(originalData, 0, originalData.Length);
return Encoding.UTF8.GetString(originalData, 0, count);
}
}
}
public class EncryptedData
{
public EncryptedData(byte[] salt, byte[] mac, byte[] data)
{
Salt = salt;
MAC = mac;
Data = data;
}
private byte[] Salt { get; set; }
public string SaltString
{
get { return Convert.ToBase64String(Salt); }
}
private byte[] MAC { get; set; }
private byte[] Data { get; set; }
public string DataString
{
get { return Convert.ToBase64String(Data); }
}
}
}
}
提供此答案的来源:如果您稍微整理一下实现,您将更容易发现问题。现在我尝试从这里使用代码,该代码给出了“padding invalid”异常。因此,当我使用来自MSDN的示例代码时,要么是空字符串,要么有时是“填充无效异常”。我发现来自MSDN的代码在有大量数据需要解密/加密的情况下不起作用。您使用的代码对小数据也不起作用,不确定原因,我也看到了Hans Passant的注释,但它不起作用。从我所看到的情况来看,你已经按照别人告诉你的那样连接好了。如果你有新问题,你需要以不同的问题发布,即。,“加密大数据的问题”需要在一个新问题中发布。不要随着您的进度更改此问题。这不是本网站应该如何工作。如果您稍微整理一下您的实现,您会更容易发现问题。现在我尝试从这里使用代码,此代码会给我“填充无效”异常。因此,当我使用来自MSDN的示例代码时,要么是空字符串,要么有时是“填充无效异常”。我发现来自MSDN的代码在有大量数据需要解密/加密的情况下不起作用。您使用的代码对小数据也不起作用,不确定原因,我也看到了Hans Passant的注释,但它不起作用。从我看到的情况来看,你已经按照别人告诉你的那样连接好了。如果你有一个新问题,你需要发布一个不同的问题,即“加密大数据的问题”需要发布在一个新问题中。不要随着你的进展更改这个问题,这不是这个网站应该如何工作。这是一样的。我在第一篇文章中详细解释了我的整个问题。我不明白为什么我有问题,我使用的是MSDN的例子。好的,你从MSDN尝试的代码对你不起作用,它对我有效,所以你需要仔细看看你有什么,并可能尝试其他东西。您是在新的控制台项目中运行了我链接的代码,还是在您现有的应用程序中运行了该代码?您使用的代码与示例不同,不同的位可能会导致您的问题,例如
generateKeyAndIv()
MSDN和您的代码正在工作,但当我尝试加密大量数据时,会出现“padding invalid or removed”(填充无效或删除)错误。generateKeyAndIV()只分配我需要通过RSA加密并发送到服务器的密钥和IV。我不能,因为“信誉点”哈哈,现在最好的事情是,当我将解决方案移动到运行在windows 2008 RC上的专用服务器时,它不起作用。嗯,是一样的。我在第一篇文章中详细解释了我的整个问题。我不明白为什么我有问题,我使用的是MSDN的例子。好的,你从MSDN尝试的代码对你不起作用,它对我有效,所以你需要仔细看看你有什么,并可能尝试其他东西。您是在新的控制台项目中运行了我链接的代码,还是在您现有的应用程序中运行了该代码?您使用的代码与示例不同,不同的位可能会导致您的问题,例如generateKeyAndIv()
MSDN和您的代码正在工作,但当我尝试加密大量数据时,会出现“padding invalid or removed”(填充无效或删除)错误。generateKeyAndIV()只分配我需要通过RSA加密并发送到服务器的密钥和IV。我不能,因为“信誉点”哈哈,现在最好的事情是,当我将解决方案移动到运行在windows 2008 RC上的专用服务器时,它不起作用。嗯