Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加密和解密查询字符串会导致追加未知文本_C#_Asp.net_C# 4.0_Encryption - Fatal编程技术网

C# 加密和解密查询字符串会导致追加未知文本

C# 加密和解密查询字符串会导致追加未知文本,c#,asp.net,c#-4.0,encryption,C#,Asp.net,C# 4.0,Encryption,Net应用程序与.Net framework 4.0。 为了加密和解密查询字符串,我使用下面的代码块。 有趣的是,当我尝试解密一个字符串,例如 string a = "username=testuser&email=testmail@yahoo.com" 解密后 string b = "username=testuser&email=testmail@yahoo.com\0\0\0\0\0\0\0\0\0\0\0" 我不知道为什么“\0”会附加到我的解密值中 我怎样才能防止这

Net应用程序与.Net framework 4.0。 为了加密和解密查询字符串,我使用下面的代码块。 有趣的是,当我尝试解密一个字符串,例如

string a = "username=testuser&email=testmail@yahoo.com"
解密后

string b = "username=testuser&email=testmail@yahoo.com\0\0\0\0\0\0\0\0\0\0\0"
我不知道为什么“\0”会附加到我的解密值中

我怎样才能防止这种情况

我用于加密和解密的代码块是-

public string EncryptQueryString(string inputText, string key, string salt)
        {
            byte[] plainText = Encoding.UTF8.GetBytes(inputText);

            using (RijndaelManaged rijndaelCipher = new RijndaelManaged())
            {
                PasswordDeriveBytes secretKey = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(key), Encoding.ASCII.GetBytes(salt));
                using (ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainText, 0, plainText.Length);
                            cryptoStream.FlushFinalBlock();
                            string base64 = Convert.ToBase64String(memoryStream.ToArray());

                            // Generate a string that won't get screwed up when passed as a query string.
                            string urlEncoded = HttpUtility.UrlEncode(base64);
                            return urlEncoded;
                        }
                    }
                }
            }
        }

        public string DecryptQueryString(string inputText, string key, string salt)
        {
            byte[] encryptedData = Convert.FromBase64String(inputText);
            PasswordDeriveBytes secretKey = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(key), Encoding.ASCII.GetBytes(salt));

            using (RijndaelManaged rijndaelCipher = new RijndaelManaged())
            {
                using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
                {
                    using (MemoryStream memoryStream = new MemoryStream(encryptedData))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainText = new byte[encryptedData.Length];
                            cryptoStream.Read(plainText, 0, plainText.Length);
                            string utf8 = Encoding.UTF8.GetString(plainText);
                            return utf8;
                        }
                    }
                }
            }
        }

更改以下行:

cryptoStream.Read(plainText, 0, plainText.Length);
string utf8 = Encoding.UTF8.GetString(plainText);
return utf8;

上述内容的另一个版本:

String outputValue = String.Empty;
using ( MemoryStream outputStream = new MemoryStream() ) {
    byte[] buffer = new byte[1024];
    int readCount = 0;
    while ((readCount = cryptoStream.Read(buffer, 0, buffer.Length)) > 0) {
        outputStream.Write(buffer, 0, readCount);
    }

    return Encoding.Unicode.GetString(outputStream.ToArray());

}
从本质上讲,读取操作是附加空字符来填充字符串。通过将其限制为解密字符的实际数量,您将获得唯一的原始字符串


上面考虑到cryptoStream.Read可能不会一次性读取整个字符串。我还没有对此进行测试(今天晚些时候将进行测试),但它看起来不错。

作为旁注:当您使用多个
语句时,您可以(也应该)省略开头和结尾块大括号,更不用说最里面的一对了。这样做可以避免不必要的缩进并提高可读性。您使用的是
cryptoStream。读取不正确。它需要反复调用,直到所有内容都被解密,并且您必须检查返回值以查看解密了多少。@MariusSchulz:我认为这是个人偏好。缩进的版本对我来说似乎更具可读性。@chrisly总是;-)。尽管如此,我还是更喜欢这种格式:扔掉那些无用的流,使用
加密程序。TransformFinalBlock
解密程序。TransformFinalBlock
读取(,,x)最多读取x字节,而不完全是x字节。因此,您当前的代码可能无法解密所有输入。最好使用StreamReader并调用ReadToEnd。@dtb:我在生产系统中有这段代码。如果我做得不对,你有更多的信息我应该看一下吗感谢“此方法的实现从当前流读取最多计数字节,并从偏移量开始将它们存储在缓冲区中。”@dtb:我可能很密集,但我没有看到问题。如果将max number设置为实际加密数据长度,那么该长度怎么可能小于解密的字节数?解密的字符串所包含的数据不会比加密的版本多。不,填充按预期工作。问题在于如何调用Read方法。不要试图通过弄乱填充物来掩盖错误。修正错误!
String outputValue = String.Empty;
using ( MemoryStream outputStream = new MemoryStream() ) {
    byte[] buffer = new byte[1024];
    int readCount = 0;
    while ((readCount = cryptoStream.Read(buffer, 0, buffer.Length)) > 0) {
        outputStream.Write(buffer, 0, readCount);
    }

    return Encoding.Unicode.GetString(outputStream.ToArray());

}