[英]Why am I able to decrypt modified encrypt data using AES 256Bit decryption
I have created a simple program for encryption and decryption. 我创建了一个简单的加密和解密程序。 I am using the
AESManaged
class in this program. 我在这个程序中使用
AESManaged
类。 The key and IV are derived from predefined password using Rfc2898DeriveBytes
. 密钥和IV是使用
Rfc2898DeriveBytes
从预定义密码Rfc2898DeriveBytes
。
I tested my program as explained below: 我测试了我的程序,如下所述:
On step #3 I was expecting an error from the program but it decrypted the wrong text. 在第3步,我期待程序出错,但它解密了错误的文本。
Can some one please help me to understand what is going wrong in my program and how to stop my program from decrypting wrong data. 有人可以帮我理解我的程序出了什么问题,以及如何阻止我的程序解密错误的数据。
Here is my program output: 这是我的程序输出:
Please put in input message
Some Text
Encrypted text is "xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCc="
Please put in encrypted text to decrypt
xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCc=
Decrypted text is "Some Text"
Please put in encrypted text to decrypt <<here I have modified "c=" to "d=">>
xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCd=
Decrypted text is "Some Text"
Enter "Exit" to exit!
AesExample.cs: AesExample.cs:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Aes_Example
{
class AesExample
{
public static void Main()
{
string action, plainText, encryptedText, decryptedText;
Begin:
Console.WriteLine("Please put in input message");
plainText = Console.ReadLine();
encryptedText = Encrypt(plainText);
Console.WriteLine("Encrypted text is \"{0}\"", encryptedText);
Console.WriteLine("Please put in encrypted text to decrypt");
encryptedText = Console.ReadLine();
decryptedText = Decrypt(encryptedText);
Console.WriteLine("Decrypted text is \"{0}\"", decryptedText);
Console.WriteLine("Please put in encrypted text to decrypt");
encryptedText = Console.ReadLine();
decryptedText = Decrypt(encryptedText);
Console.WriteLine("Decrypted text is \"{0}\"", decryptedText);
Console.WriteLine("Enter \"Exit\" to exit!");
action = Console.ReadLine();
if (action.ToUpper() != "EXIT") { goto Begin; }
}
public static string Encrypt(string clearText)
{
string EncryptionKey = "TESTPWD@#52";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (AesManaged encryptor = new AesManaged())
{
Rfc2898DeriveBytes pdb = new
Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
public static string Decrypt(string cipherText)
{
string EncryptionKey = "TESTPWD@#52";
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (AesManaged encryptor = new AesManaged())
{
Rfc2898DeriveBytes pdb = new
Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
}
}
That last ="
part of your string is padding. 那个last
="
你的字符串的一部分是填充。
And not even cryptographic padding but Base64 padding. 甚至加密填充,但Base64填充。
The short version: 简短版本:
byte[] data = { 1, 2, 3, 4 };
clearText = Convert.ToBase64String(data);
cipherText = clearText.Replace("A==", "B=="); // crude test
byte[] cipherBytes = Convert.FromBase64String(cipherText);
After this, cipherBytes
will still be { 1, 2, 3, 4 }
在此之后,
cipherBytes
仍然是{ 1, 2, 3, 4 }
Base64 encoding uses 6 bits/char, so when you have N bytes it will need (N*8)/6 chars. Base64编码使用6位/字符,所以当你有N个字节时,它将需要(N * 8)/ 6个字符。 Usually this means that there are some left-over bits and the last char has some room to play.
通常这意味着有一些遗留位,最后一个字符有一些空间可以播放。 But only a little and only in the last char.
但只有一点点,只有最后一个字符。
Besides what is said you need to realize that low-level encryption and decryption is just a bit transformation. 除了所说的,你需要意识到低级加密和解密只是一点点转换。 It doesn't know what input and output is and what it should be.
它不知道输入和输出是什么以及它应该是什么。 Ie if you encrypt 16 bytes, modify the 5th byte and decrypt those 16 bytes back, you will get output which doesn't correspond to the data you encrypted, but you won't get an error either.
即如果你加密16个字节,修改第5个字节并解密那16个字节,你将获得与你加密的数据不对应的输出,但你也不会得到错误。
For changes to be detected you need to employ some kind of integrity checking. 要检测更改,您需要使用某种完整性检查。 This is usually done in high-level encryption schemes such as OpenPGP or CMS or protocols like SSL/TLS and SSH.
这通常在高级加密方案(如OpenPGP或CMS)或协议(如SSL / TLS和SSH)中完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.