gpt4 book ai didi

.net - RijndaelManaged "Padding is invalid and cannot be removed"仅在生产中解密时发生

转载 作者:行者123 更新时间:2023-12-03 20:12:51 33 4
gpt4 key购买 nike

我知道有人对此提出了其他问题,但到目前为止还没有提供解决方案或正是我遇到的问题。

下面的类处理字符串的加密和解密,传入的 key 和向量始终相同。

被加密和解密的字符串总是数字,大多数工作但偶尔会在解密时失败(但仅在生产服务器上)。我应该提到本地和生产环境都在 Windows Server 2003 上的 IIS6 中,使用该类的代码位于 .ashx 处理程序中。在生产服务器上失败的例子是“0000232668”

错误信息是

System.Security.Cryptography.CryptographicException:填充无效且无法删除。
在 System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)

对于代码

 public class Aes
{
private byte[] Key;
private byte[] Vector;

private ICryptoTransform EncryptorTransform, DecryptorTransform;
private System.Text.UTF8Encoding UTFEncoder;

public Aes(byte[] key, byte[] vector)
{
this.Key = key;
this.Vector = vector;

// our encyption method
RijndaelManaged rm = new RijndaelManaged();

rm.Padding = PaddingMode.PKCS7;

// create an encryptor and decyptor using encryption method. key and vector
EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);

// used to translate bytes to text and vice versa
UTFEncoder = new System.Text.UTF8Encoding();
}

/// Encrypt some text and return a string suitable for passing in a URL.
public string EncryptToString(string TextValue)
{
return ByteArrToString(Encrypt(TextValue));
}

/// Encrypt some text and return an encrypted byte array.
public byte[] Encrypt(string TextValue)
{
//Translates our text value into a byte array.
Byte[] bytes = UTFEncoder.GetBytes(TextValue);
Byte[] encrypted = null;

//Used to stream the data in and out of the CryptoStream.
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
}

encrypted = memoryStream.ToArray();
}

return encrypted;
}

/// The other side: Decryption methods
public string DecryptString(string EncryptedString)
{
return Decrypt(StrToByteArray(EncryptedString));
}

/// Decryption when working with byte arrays.
public string Decrypt(byte[] EncryptedValue)
{
Byte[] decryptedBytes = null;

using (MemoryStream encryptedStream = new MemoryStream())
{
using (CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write))
{
decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
}

decryptedBytes = encryptedStream.ToArray();
}

return UTFEncoder.GetString(decryptedBytes);
}

/// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
// System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
// return encoding.GetBytes(str);
// However, this results in character values that cannot be passed in a URL. So, instead, I just
// lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
public byte[] StrToByteArray(string str)
{
if (str.Length == 0)
throw new Exception("Invalid string value in StrToByteArray");

byte val;
byte[] byteArr = new byte[str.Length / 3];
int i = 0;
int j = 0;
do
{
val = byte.Parse(str.Substring(i, 3));
byteArr[j++] = val;
i += 3;
}
while (i < str.Length);
return byteArr;
}

// Same comment as above. Normally the conversion would use an ASCII encoding in the other direction:
// System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
// return enc.GetString(byteArr);
public string ByteArrToString(byte[] byteArr)
{
byte val;
string tempStr = "";
for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
{
val = byteArr[i];
if (val < (byte)10)
tempStr += "00" + val.ToString();
else if (val < (byte)100)
tempStr += "0" + val.ToString();
else
tempStr += val.ToString();
}
return tempStr;
}

编辑:感谢您的所有帮助,但是您的回答并没有解决问题,结果证明这是一件非常简单的事情。我在一台服务器上生成了一个加密字符串,然后将它交给另一台服务器上的处理程序进行解密和处理,但事实证明,在不同的服务器上运行时,加密的结果不同,因此接收服务器无法对其进行解密。其中一个答案偶然发现了这个暗示,这就是我接受它的原因

最佳答案

我倾向于明确地调用 FlushFinalBlock CryptoStream 上的方法,然后再关闭它。这意味着在您的加密方法中执行以下操作:

using (CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write))
{
cs.Write(bytes, 0, bytes.Length);
cs.FlushFinalBlock();
}

如果您不这样做,则可能是加密数据被截断 - 这将导致“无效填充”情况。使用 PKCS7 时始终存在填充,即使被加密的数据与密码的块长度对齐。

关于.net - RijndaelManaged "Padding is invalid and cannot be removed"仅在生产中解密时发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2116607/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com