如何使QueryString不可更改?

时间:2013-04-17 07:39:51

标签: c# asp.net query-string

我正在使用asp.net实现该应用程序。

我想让querysting不可更改。如果我手动进行更改,则需要抛出一些异常。

我该如何实施?

1 个答案:

答案 0 :(得分:1)

“尝试加密查询字符串并将结果字符串附加到查询字符串。在读取查询字符串时,首先再次加密常规参数并将其与字符串进行比较。然后当任何参数发生更改时,哈希将不再匹配你可以抛出异常。

像这样的东西。搜索一个很好的Querystring读者/作家类,让生活更轻松。

private string GetSecureQsToken(string querystring)
{
    Byte[] buffer = Encoding.UTF8.GetBytes(querystring);
    SHA1CryptoServiceProvider cryptoTransformSha1 =
    new SHA1CryptoServiceProvider();
    string hash = BitConverter.ToString(
        cryptoTransformSha1.ComputeHash(buffer)).Replace("-", "");

    return hash;
}

private void GoToSecureQsPage()
{
    string qsvalues = "id=1&page=4";
    Response.Redirect(string.Format("Default.aspx?{0}&hash={1}", qsvalues, GetSecureQsToken(qsvalues)));
}

private void ReadSecureQs()
{
    //here check the normal querystring parameters again against the hash parameter
    if (GetSecureQsToken("id=1&page=4") != Request.QueryString["hash"])
    {
        throw new Exception("Error here");
    }
}

我只是按照评论中的建议去了哈希版本,但是是的,然后客户再次变得可变。所以你需要这样的加密:

public class SecureQuerystring
{
    public SecureQuerystring()
    {
        m_passPhrase = "#oqT6%hKg";
        m_saltValue = "7651273512";
        m_initVector = "@1B2c3D4e5F6g7H8";
        m_hashAlgorithm = "SHA1";
        m_passwordIterations = 5;
        m_keySize = 128;
    }


    private string m_plaintext;
    private string m_ciphertext;
    private byte[] m_plaintextbytes;
    private byte[] m_ciphertextbytes;
    private string m_passPhrase;
    private string m_saltValue;
    private string m_hashAlgorithm;
    private Int32 m_passwordIterations;
    private string m_initVector;
    private Int32 m_keySize;


    public string plaintext
    {
        get { return m_plaintext; }
        set { m_plaintext = value; }
    }


    public string ciphertext
    {
        get { return m_ciphertext; }
        set { m_ciphertext = value; }
    }


    public byte[] plaintextbytes
    {
        get { return m_plaintextbytes; }
        set { m_plaintextbytes = value; }
    }


    public byte[] ciphertextbytes
    {
        get { return m_ciphertextbytes; }
        set { m_ciphertextbytes = value; }
    }


    public string passPhrase
    {
        get { return m_passPhrase; }
        set { m_passPhrase = value; }
    }


    public string saltValue
    {
        get { return m_saltValue; }
        set { m_saltValue = value; }
    }


    public string hashAlgorithm
    {
        get { return m_hashAlgorithm; }
        set { m_hashAlgorithm = value; }
    }


    public Int32 passwordIterations
    {
        get { return m_passwordIterations; }
        set { m_passwordIterations = value; }
    }


    public string initVector
    {
        get { return m_initVector; }
        set { m_initVector = value; }
    }


    public Int32 keySize
    {
        get { return m_keySize; }
        set { m_keySize = value; }
    }

    public string ASCIIEncrypt(string plaintext2)
    {
        try
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(m_initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(m_saltValue);
            byte[] plainTextBytes = Encoding.ASCII.GetBytes(plaintext2);
            PasswordDeriveBytes password = new PasswordDeriveBytes(m_passPhrase, saltValueBytes, m_hashAlgorithm, m_passwordIterations);
            byte[] keyBytes = password.GetBytes(m_keySize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] cipherTextBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            m_ciphertext = Convert.ToBase64String(cipherTextBytes);
            return "SUCCESS";
        }
        catch (Exception ex)
        {
            return ex.Message.ToString();
        }


    }

    public string ASCIIDecrypt(string ciphertext2)
    {
        try
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(m_initVector);
            byte[] saltValueBytes = Encoding.ASCII.GetBytes(m_saltValue);
            byte[] cipherTextBytes = Convert.FromBase64String(ciphertext2);
            PasswordDeriveBytes password = new PasswordDeriveBytes(m_passPhrase, saltValueBytes, m_hashAlgorithm, m_passwordIterations);
            byte[] keyBytes = password.GetBytes(keySize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
            m_plaintext = Encoding.ASCII.GetString(plainTextBytes);
            return "SUCCESS";


        }
        catch (Exception ex)
        {
            return ex.Message.ToString();
        }


    }


}

所以在qyerstring中附加ASCIIEncrypt(“没有加密字符串的你的字符串”),并在读取时再次读取正常的qs参数并将qs中的散列与结果进行比较。