GARANTIR DESCONTO

Fórum Utilização correta e segura de QueryString #6804

15/06/2009

0

Boa noite, Estou implementando querystring em minha aplicação principalmente no logon do usuário. Gostaria de saber como poderia criptografar a querystring para que um possivel invasor não utilize desses dados para entrar em minha aplicação. Qual forma também poderia utilizar para que a chave gerada seja aleatória e tenha um tempo de vida ( principalmente tratando-se de logon de usuários ) Abraços Vinicius
Vinicius Cezar

Vinicius Cezar

Responder

Posts

16/06/2009

Fabio Mans

Olá Vinícios, muito boa sua dúvida, poucos programadores se preocupam com este assunto.

Nos meu programas eu utilizo a classe abaixo.





StringHelpers.cs

using System;
using System.Web;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Collections.Specialized;

public class StringHelpers
{
    #region Constants

    private const char QUERY_STRING_DELIMITER = '&';

    #endregion Constants

    #region Members

    private static RijndaelManaged _cryptoProvider;
    //128 bit encyption: DO NOT CHANGE   
    private static readonly byte[] Key = { 18, 19, 8, 24, 36, 22, 4, 22, 17, 5, 11, 9, 13, 15, 06, 23 };
    private static readonly byte[] IV = { 14, 2, 16, 7, 5, 9, 17, 8, 4, 47, 16, 12, 1, 32, 25, 18 };

    #endregion Members

    #region Constructor

    static StringHelpers()
    {
        _cryptoProvider = new RijndaelManaged();
        _cryptoProvider.Mode = CipherMode.CBC;
        _cryptoProvider.Padding = PaddingMode.PKCS7;
    }

    #endregion Constructor

    #region Methods

    /// <summary>
    /// Encrypts a given string.
    /// </summary>
    /// <param name="unencryptedString">Unencrypted string</param>
    /// <returns>Returns an encrypted string</returns>
    public static string Encrypt(string unencryptedString)
    {
        byte[] bytIn = ASCIIEncoding.ASCII.GetBytes(unencryptedString);

        // Create a MemoryStream
        MemoryStream ms = new MemoryStream();

        // Create Crypto Stream that encrypts a stream
        CryptoStream cs = new CryptoStream(ms,
            _cryptoProvider.CreateEncryptor(Key, IV),
            CryptoStreamMode.Write);

        // Write content into MemoryStream
        cs.Write(bytIn, 0, bytIn.Length);
        cs.FlushFinalBlock();

        byte[] bytOut = ms.ToArray();
        return Convert.ToBase64String(bytOut);
    }

    /// <summary>
    /// Decrypts a given string.
    /// </summary>
    /// <param name="encryptedString">Encrypted string</param>
    /// <returns>Returns a decrypted string</returns>
    public static string Decrypt(string encryptedString)
    {
        if (encryptedString.Trim().Length != 0)
        {
            // Convert from Base64 to binary
            byte[] bytIn = Convert.FromBase64String(encryptedString);

            // Create a MemoryStream
            MemoryStream ms = new MemoryStream(bytIn, 0, bytIn.Length);

            // Create a CryptoStream that decrypts the data
            CryptoStream cs = new CryptoStream(ms,
                _cryptoProvider.CreateDecryptor(Key, IV),
                CryptoStreamMode.Read);

            // Read the Crypto Stream
            StreamReader sr = new StreamReader(cs);

            return sr.ReadToEnd();
        }
        else
        {
            return "";
        }
    }


    public static NameValueCollection DecryptQueryString(string queryString)
    {
        if (queryString.Length != 0)
        {
            //Decode the string
            string decodedQueryString = HttpUtility.UrlDecode(queryString);

            //Decrypt the string
            string decryptedQueryString = Decrypt(decodedQueryString);

            //Now split the string based on each parameter
            string[] actionQueryString = decryptedQueryString.Split(new char[] { QUERY_STRING_DELIMITER });

            NameValueCollection newQueryString = new NameValueCollection();

            //loop around for each name value pair.
            for (int index = 0; index < actionQueryString.Length; index++)
            {
                string[] queryStringItem = actionQueryString[index].Split(new char[] { '=' });
                newQueryString.Add(queryStringItem[0], queryStringItem[1]);
            }

            return newQueryString;
        }
        else
        {
            //No query string was passed in.
            return null;
        }
    }

    public static string EncryptQueryString(NameValueCollection queryString)
    {
        //create a string for each value in the query string passed in.
        string tempQueryString = "";

        for (int index = 0; index < queryString.Count; index++)
        {
            tempQueryString += queryString.GetKey(index) + "=" + queryString[index];
            if (index != queryString.Count - 1)
            {
                tempQueryString += QUERY_STRING_DELIMITER;
            }
        }

        return EncryptQueryString(tempQueryString);
    }

    /// <summary>
    /// You must pass in a string that uses the QueryStringHelper.DELIMITER as the delimiter.
    /// This will also append the "?" to the beginning of the query string.
    /// </summary>
    /// <param name="queryString"></param>
    /// <returns></returns>
    public static string EncryptQueryString(string queryString)
    {
        return string.Format("?", HttpUtility.UrlEncode(Encrypt(queryString)));
    }

    #endregion Methods
}


Em outra classe chamada BasePage eu crie os seguintes métodos


using System;
using System.Collections.Specialized;
using System.IO;
using System.Web.UI;
using System.Web.UI.HtmlControls;


public class BasePage : Page
{

  protected override void OnLoad(EventArgs e)
    {
        // add onfocus and onblur javascripts to all input controls on the forum,
        // so that the active control has a difference appearance
        Helpers.SetInputControlsHighlight(this, "highlight");


        // Set the page's title, if necessary
        if (string.IsNullOrEmpty(Page.Title) || Page.Title == "Untitled Page")
        {
            // Determine the filename for this page
            string fileName = Path.GetFileNameWithoutExtension(Request.PhysicalPath);

            Page.Title = "GRUPO SBF - R&S Solicitação de Contratação - (" + fileName + ")";
        }


        HtmlMeta metaDescription = new HtmlMeta();
        metaDescription.Name = "description";
        metaDescription.Content = "SELAÇÃO";
                                      
                                        
                                      

      
        //Define uma tag metadata
     
        //Adicionando
        Page.Header.Controls.Add(metaDescription);

        base.OnLoad(e);
    }
   


    public static NameValueCollection DecryptQueryString(string queryString)
    {
        return StringHelpers.DecryptQueryString(queryString);
    }
   

    public static string EncryptQueryString(NameValueCollection queryString)
    {
        return StringHelpers.EncryptQueryString(queryString);
    }


    public static string EncryptQueryString(string queryString)
    {
        return StringHelpers.EncryptQueryString(queryString);
    }
}


Enfim para criptografar eu faço o seguinte

string solicitacao = EncryptQueryString("solicitacao=" + 1089);

Para recuperar

NameValueCollection queryString = DecryptQueryString(Request.QueryString.ToString());
        if (queryString != null)
        {
            int idSolicitacao = Convert.ToInt32(queryString["solicitacao"]); //Resultado 1089
           
        }


Resumindo crie duas classes conforme o exemplo abaixo

Na página você deve herdar a BasePage

public partial class ConsultaSolicitacao : BasePage (Minha página herdando de basepage


Espero ter ajudado.

Fabio









Responder

Gostei + 0

17/06/2009

Vinicius Cezar

Caro Mans, Obrigado pelo seu post. Desde segunda-feira estava com problemas aqui para responder ou qualquer outra ação, mas parece que melhorou. Como programo em VB.NET, vou converter e testar nesse final de semana e te passo um feed-back. Forte abraço! Vinicius
Responder

Gostei + 0

18/06/2009

Fabio Mans

Olá, você pode colocar uma classe C# em um projeto VB na pasta App_Code, não tem problema.

Fabio
Responder

Gostei + 0

23/06/2009

Devmedia

Vinicius,
a resposta do consultor solucionou a sua dúvida? Podemos encerrar o chamado?
Responder

Gostei + 0

25/06/2009

Devmedia

Vinicius,
por falta de retorno estamos encerrando o chamado. Caso ainda tenha dúvidas sobre o assunto aqui abordado, por favor, poste neste mesmo chamado que o consultor voltará a lhe atender.
Responder

Gostei + 0

14/07/2009

Vinicius Cezar

Obrigado Fabio pelo atendimento. Estive de férias e voltei agora. Vou implementar mas creio que já está 100%. qualquer dúvida te procuro. Obrigado.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar