3

.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;
                        }
                    }
                }
            }
        }
4

1 に答える 1

2

次の行を変更します。

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

StringBuilder outputValue = new StringBuilder();

byte[] buffer = new byte[1024];
int readCount = cryptoStream.Read(buffer, 0, buffer.Length);
while (readCount > 0) {
    outputValue.Append(Encoding.UTF8.GetString(buffer, 0, readCount));
    readCount = cryptoStream.Read(buffer, 0, buffer.Length);
}

return outputValue.ToString();

上記の別のバージョン:

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());

}

基本的に、Read は null 文字を追加して文字列を埋めます。復号化された実際の文字数に制限することで、元の文字列のみが返されます。

上記では、cryptoStream.Read が一度に文字列全体を読み取れない可能性があることを考慮しています。これはまだテストしていませんが (今日中にテストします)、良さそうです。

于 2013-09-17T13:51:44.943 に答える