Rijndael 加密文本导致要解密的数据长度无效错误 - C#
Rijndael encrypted text causes length of data to decrypt is invalid error - C#
我在网上搜索过,但没有找到解决我问题的方法。
我正在使用以前编写的方法使用 Rijndael 加密和加密文本 class。
我使用这些函数为我一直在开发的 Web 应用程序加密和解密用户名和电子邮件。
encryption/decryption 完美运行,但我偶尔会收到此错误:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
目前,我在使用特定电子邮件地址时遇到此错误,即使我替换了电子邮件中的某些字母也无法重现该错误。
这里是 encryption/decrytpion 函数。 IV 和 Key 被定义为只读字符串。
static public string Encrypting(string Source)
{
byte[] bytIn = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
// create a MemoryStream so that the process can be done without I/O files
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] IVBytes = Encoding.ASCII.GetBytes(IV);
byte[] KEYBytes = Encoding.ASCII.GetBytes(KEY);
Rijndael rijndael = Rijndael.Create();
rijndael.IV = IVBytes;
rijndael.Key = KEYBytes;
// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(ms, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
// write out encrypted content into MemoryStream
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
// get the output and trim the '[=11=]' bytes
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;
// convert into Base64 so that the result can be used in xml
return System.Convert.ToBase64String(bytOut, 0, i);
}
static public string Decrypting(string Source)
{
// convert from Base64 to binary
byte[] bytIn = System.Convert.FromBase64String(Source);
// create a MemoryStream with the input
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);
byte[] IVBytes = Encoding.ASCII.GetBytes(IV);
byte[] KEYBytes = Encoding.ASCII.GetBytes(KEY);
Rijndael rijndael = Rijndael.Create();
rijndael.IV = IVBytes;
rijndael.Key = KEYBytes;
// create Crypto Stream that transforms a stream using the decryption
CryptoStream cs = new CryptoStream(ms, rijndael.CreateDecryptor(), CryptoStreamMode.Read);
// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader(cs);
return sr.ReadToEnd();
}
仅供参考 - 我对密码学和安全性还很陌生。
是否可以修复这些函数以避免导致错误的特殊情况,或者我应该放弃这些并使用 RijndaelManaged
class?
我发现使用 RijndaelManaged 的站点:
SeeSharp
错误的标准是填充问题。您使用的是什么版本的 .NET?更常见的是使用 AES 类(AES,即高级加密标准,即 Rijndael)。您可以找到大量 AES 实现作为示例。
如果您需要证明 AES 是 Rijndael:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
这个问题几乎可以肯定与 Rijndael
与 RijndaelManaged
(或任何其他此类实现)无关,而是因为加密数据包含 0x00
,而您错误地假设密文在第一个 0x00
字节结束。由于密文可以合法地包含 any 字节值,因此您应该使用流的 Length
属性 来确定密文的长度。
删除您评论的部分:"get the output and trim the '[=25=]' bytes" 并将 return ...
语句替换为:
return System.Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length);
应该注意的是,您在这里使用密码学还有很多其他问题,例如使用直接从字符串的 ASCII 编码生成的密钥,以及您使用固定 IV 的事实都会对安全性产生负面影响。
我在网上搜索过,但没有找到解决我问题的方法。
我正在使用以前编写的方法使用 Rijndael 加密和加密文本 class。
我使用这些函数为我一直在开发的 Web 应用程序加密和解密用户名和电子邮件。
encryption/decryption 完美运行,但我偶尔会收到此错误:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
目前,我在使用特定电子邮件地址时遇到此错误,即使我替换了电子邮件中的某些字母也无法重现该错误。
这里是 encryption/decrytpion 函数。 IV 和 Key 被定义为只读字符串。
static public string Encrypting(string Source)
{
byte[] bytIn = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
// create a MemoryStream so that the process can be done without I/O files
System.IO.MemoryStream ms = new System.IO.MemoryStream();
byte[] IVBytes = Encoding.ASCII.GetBytes(IV);
byte[] KEYBytes = Encoding.ASCII.GetBytes(KEY);
Rijndael rijndael = Rijndael.Create();
rijndael.IV = IVBytes;
rijndael.Key = KEYBytes;
// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(ms, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
// write out encrypted content into MemoryStream
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
// get the output and trim the '[=11=]' bytes
byte[] bytOut = ms.GetBuffer();
int i = 0;
for (i = 0; i < bytOut.Length; i++)
if (bytOut[i] == 0)
break;
// convert into Base64 so that the result can be used in xml
return System.Convert.ToBase64String(bytOut, 0, i);
}
static public string Decrypting(string Source)
{
// convert from Base64 to binary
byte[] bytIn = System.Convert.FromBase64String(Source);
// create a MemoryStream with the input
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);
byte[] IVBytes = Encoding.ASCII.GetBytes(IV);
byte[] KEYBytes = Encoding.ASCII.GetBytes(KEY);
Rijndael rijndael = Rijndael.Create();
rijndael.IV = IVBytes;
rijndael.Key = KEYBytes;
// create Crypto Stream that transforms a stream using the decryption
CryptoStream cs = new CryptoStream(ms, rijndael.CreateDecryptor(), CryptoStreamMode.Read);
// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader(cs);
return sr.ReadToEnd();
}
仅供参考 - 我对密码学和安全性还很陌生。
是否可以修复这些函数以避免导致错误的特殊情况,或者我应该放弃这些并使用 RijndaelManaged
class?
我发现使用 RijndaelManaged 的站点: SeeSharp
错误的标准是填充问题。您使用的是什么版本的 .NET?更常见的是使用 AES 类(AES,即高级加密标准,即 Rijndael)。您可以找到大量 AES 实现作为示例。
如果您需要证明 AES 是 Rijndael:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
这个问题几乎可以肯定与 Rijndael
与 RijndaelManaged
(或任何其他此类实现)无关,而是因为加密数据包含 0x00
,而您错误地假设密文在第一个 0x00
字节结束。由于密文可以合法地包含 any 字节值,因此您应该使用流的 Length
属性 来确定密文的长度。
删除您评论的部分:"get the output and trim the '[=25=]' bytes" 并将 return ...
语句替换为:
return System.Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length);
应该注意的是,您在这里使用密码学还有很多其他问题,例如使用直接从字符串的 ASCII 编码生成的密钥,以及您使用固定 IV 的事实都会对安全性产生负面影响。