2015-05-19 121 views
0

我已经在网上搜索,但一直没能找到任何解决方案,我的问题。Rijndael加密文本导致解密数据的长度是无效的错误 - C#

我使用以前编写的方法来使用Rijndael类对文本进行加密和删除。

我使用这些函数来加密和解密我一直在处理的Web应用程序的用户名和电子邮件。

加密/解密完美的作品,但每过一段时间,我得到这个错误:

System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid. 

目前,我正与一个特定的电子邮件地址收到这个错误,我甚至不能重现错误如果我替换电子邮件中的一些字母。

以下是加密/解密函数。 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 '\0' 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类?

网站我发现,使用RijndaelManaged的: SeeSharp

TekEye

+0

http://pastebin.com/BNHLU1Tc试试这个,并说如果会出现相同的错误。我看到的问题与解密数据的无效填充有关。或者解密数据填充的无效设置,所以该方法无法计算没有填充的纯加密字节的正确大小。 – Kosmos

+0

您是否验证过您尝试解密的值是使用相同的文本编码进行加密的? –

+0

@Kosmos - 谢谢,我会玩这个。 – RXC

回答

1

的问题是几乎可以肯定无关RijndaelRijndaelManaged(或任何其他此类的实现),而是因为加密的数据包含一个0x00和您错误地认为密文在第一个字节0x00处结束。由于密文可以合法地包含任何字节值,所以应该使用流的Length属性来确定密文的长度。

消除您评论过的部分:“得到的输出,并修剪‘\ 0’字节”,取而代之的return ...声明:

return System.Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length); 

应当指出的是,还有许多其他问题你在这里使用密码术,例如使用直接从字符串的ASCII编码生成的密钥,以及您使用固定IV的事实都会对安全性产生负面影响。

+0

谢谢。这解决了我的问题,虽然ms.Length很长,但我必须使用'System.Convert.ToInt32(ms.Length)'将其转换为int。 – RXC

+0

@RXC直接转换为'int'应该没问题(即'(int)ms.Length'),不需要更长的'System.Convert ...'。 – Iridium

0

为错误的规范是一个填充问题。你使用的是什么版本的.NET?使用AES类(AES或高级加密标准,即Rijndael)更为常见。有很多AES实现可以作为示例找到。

如果你需要一些证据AES是Rijndael算法:http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

+0

我正在使用.Net 3.5。感谢维基链接。我曾希望,也许有一个简单的解决方案,但我可能会更好,就像你说的使用不同的实现。 – RXC

相关问题