您好我想要加密和解密文本。我的加密代码工作正常,匹配我想要的值。但是当我想要Decrypt时,这会给出错误padding is invalid and cannot be removed
。在下面的代码中,我首先给出了我的加密和解密代码。此外,我必须修复此错误Stack overflow link,StackoverlFlow Link 2,但无法解决此问题。
string getHashKey1 = EncryptText("10002:1486703720424", "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");
结果= 1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=
string reverseKey = DecryptText('1ltQFLRGNif73uCNzi0YEvBqLKiRgx6fWsk5e/GcTQc=', "hpIw4SgN)TxJdoQj=GKo)p83$uHePgoF");
当我添加AES_Decrypt aes.Padding = PaddingMode.Zeros;我得到低于结果。
结果: - ����y�7�t���Ij���,���� Z��$�
public string EncryptText(string input, string password)
{
string result = "";
try
{
// Get the bytes of the string
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
result = Convert.ToBase64String(bytesEncrypted);
return result;
}
catch (Exception ex)
{
}
return result;
}
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
try
{
using (MemoryStream ms = new MemoryStream())
{
using (Aes aes = Aes.Create())
{
aes.Key = passwordBytes;
aes.Mode = CipherMode.ECB;
// "zero" IV
aes.IV = new byte[16];
using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
}
catch (Exception ex)
{
}
return encryptedBytes;
}
以上代码适用于加密。
以下代码提供错误
padding is invalid and cannot be removed
public string DecryptText(string input, string password)
{
// Get the bytes of the string
byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
string result = Encoding.UTF8.GetString(bytesDecrypted);
return result;
}
public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
using (MemoryStream ms = new MemoryStream())
{
using (Aes aes = Aes.Create())
{
aes.Key = passwordBytes;
aes.Mode = CipherMode.ECB;
aes.IV = new byte[16];
using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close(); // here i am getting error
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
答案 0 :(得分:3)
你有两个问题:
1)(已经由pedrofb指出):您在加密时使用UTF8.GetBytes
,但在解密中使用SHA256(UTF8.GetBytes())
。
您不应该使用这些方法中的任何一种,而应使用适当的基于密码的密钥派生函数,例如PBKDF2。在.NET中,PBKDF2可通过Rfc2898DeriveBytes
类获得。
byte[] salt = 8 or more bytes that you always pass in as the same.
// (salt could be fixed for your application,
// but if you have users it should be unique per user and stored along with the output value)
int iterations = 100000;
// Or bigger. If you were making a user management system you
// should write this number down, too, so you can increase it over time;
// it should be whatever number makes it take 100ms or more on the fastest relevant computer)
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations);
passwordBytes = pbkdf2.GetBytes(16); // 16 = AES128, 24 = AES192, 32 = AES256.
2)您在加密时使用Base64编码,但在解密时使用UTF8.GetBytes。
奖金问题:
3)您正在使用电子密码本(ECB)链接。建议使用密码块链(CBC),而不是ECB。
要正确使用CBC,请在加密中生成随机初始化向量(IV)(在创建新的Aes
对象时自动完成,或者如果您在加密时调用GenerateIV()
重用对象)。然后,您可以将IV(对于AES将始终为16个字节)添加到密文。在解密中,您可以a)中断前16个字节并将其指定为IV(然后解密其余数据)或b)解密整个blob并忽略解密输出的前16个字节。
答案 1 :(得分:1)
解密时正在哈希密码,
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
但不是加密时。这意味着您使用的是不同的密码