我有以下使用
更新:请参考如何为Base64应用填充。我们可以使用
使用Base64作为源输入会导致一些值出现问题,例如“ MyTest”,其中字符串长度不是4的倍数。 相关要点: 要解密使用SymmetricAlgorithm类之一加密的数据,您必须将Key属性和IV属性设置为加密时使用的相同值。
SymmetricAlgorithm.IV属性:来自前一个块的信息被混入到加密下一个块的过程中。因此,两个相同的纯文本块的输出是不同的。由于这种技术使用前一个块来加密下一个块,因此需要初始化向量来加密第一个数据块。(根据SymmetricAlgorithm.IV Property MSDN文章)
有效的Key大小为:128、192、256位(根据How many characters to create a byte array for my AES method?)
AesCryptoServiceProvider
进行加密和解密的代码。用于加密和解密的iv
和key
是相同的。但是,解密后的值与原始字符串不同。
- 需要进行哪些更正才能在解密后获得原始值?
- 当
inputString =“Test”
时,此代码仅在inputValue = valid128BitString
时有效。我收到以下异常Padding is invalid and cannot be removed.
。我们如何进行更正?
更新的问题
根据@jbtule答案,以下内容将解决问题。
encyptedValue.IV = result.IV;
加密结果中的IV
值会发生变化。假设加密是在单独的进程中完成的,我们如何知道解密时所需的IV呢?有没有一种方法可以使其恒定或已知?
答案:您的另一个选项是将IV传递到加密中,在开始加密转换之前分配它,而不是让aesProvider为您生成随机IV。- @Scott Chamberlain
aesProvider.IV = Convert.FromBase64String("4uy34C9sqOC9rbV4GD8jrA==");
更新:请参考如何为Base64应用填充。我们可以使用
UTF8
来编码源输入和结果输出。密钥和IV可以保留在Base64
中。使用Base64作为源输入会导致一些值出现问题,例如“ MyTest”,其中字符串长度不是4的倍数。 相关要点: 要解密使用SymmetricAlgorithm类之一加密的数据,您必须将Key属性和IV属性设置为加密时使用的相同值。
SymmetricAlgorithm.IV属性:来自前一个块的信息被混入到加密下一个块的过程中。因此,两个相同的纯文本块的输出是不同的。由于这种技术使用前一个块来加密下一个块,因此需要初始化向量来加密第一个数据块。(根据SymmetricAlgorithm.IV Property MSDN文章)
有效的Key大小为:128、192、256位(根据How many characters to create a byte array for my AES method?)
class Program
{
static void Main(string[] args)
{
string valid128BitString = "AAECAwQFBgcICQoLDA0ODw==";
string inputValue = valid128BitString;
string keyValue = valid128BitString;
string iv = valid128BitString;
byte[] byteValForString = Convert.FromBase64String(inputValue);
EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue);
EncryptResult encyptedValue = new EncryptResult();
encyptedValue.IV = iv;
encyptedValue.EncryptedMsg = result.EncryptedMsg;
string finalResult = Convert.ToBase64String(Aes128Utility.DecryptData(encyptedValue, keyValue));
Console.WriteLine(finalResult);
if (String.Equals(inputValue, finalResult))
{
Console.WriteLine("Match");
}
else
{
Console.WriteLine("Differ");
}
Console.ReadLine();
}
}
AES实用工具
public static class Aes128Utility
{
private static byte[] key;
public static EncryptResult EncryptData(byte[] rawData, string strKey)
{
EncryptResult result = null;
if (key == null)
{
if (!String.IsNullOrEmpty(strKey))
{
key = Convert.FromBase64String((strKey));
result = Encrypt(rawData);
}
}
else
{
result = Encrypt(rawData);
}
return result;
}
public static byte[] DecryptData(EncryptResult encryptResult, string strKey)
{
byte[] origData = null;
if (key == null)
{
if (!String.IsNullOrEmpty(strKey))
{
key = Convert.FromBase64String(strKey);
origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
}
}
else
{
origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
}
return origData;
}
private static EncryptResult Encrypt(byte[] rawData)
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
aesProvider.Key = key;
aesProvider.Mode = CipherMode.CBC;
aesProvider.Padding = PaddingMode.PKCS7;
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream encStream = new CryptoStream(memStream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write);
encStream.Write(rawData, 0, rawData.Length);
encStream.FlushFinalBlock();
EncryptResult encResult = new EncryptResult();
encResult.EncryptedMsg = Convert.ToBase64String(memStream.ToArray());
encResult.IV = Convert.ToBase64String(aesProvider.IV);
return encResult;
}
}
}
private static byte[] Decrypt(byte[] encryptedMsg, byte[] iv)
{
using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
{
aesProvider.Key = key;
aesProvider.IV = iv;
aesProvider.Mode = CipherMode.CBC;
aesProvider.Padding = PaddingMode.PKCS7;
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream decStream = new CryptoStream(memStream, aesProvider.CreateDecryptor(), CryptoStreamMode.Write);
decStream.Write(encryptedMsg, 0, encryptedMsg.Length);
decStream.FlushFinalBlock();
return memStream.ToArray();
}
}
}
}
DTO类
public class EncryptResult
{
public string EncryptedMsg { get; set; }
public string IV { get; set; }
}
参考资料
byte[] byteValForString = Convert.FromBase64String("Test");
对于你的明文是无效的。 - jbtuleaesProvider.Padding = PaddingMode.None
?看看是否有效?不知道为什么使用相同的填充方式会出现错误? - Amitd