Desenvolvimento - ADO.NET

Desenvolvendo uma aplicação CRUD com Desing Patterns – (parte 3) - Construindo o FrameWork...

Neste artigo iremos abordar a criação de uma classe para criptografia de dados onde iremos implementar padrões de segurança.

por Vitor Meriat



"A ciência dos projetos consiste em prever as dificuldades de execução.

[Vauvenargues , Luc de Clapiers]

Olá pessoal.

Este é o terceiro artigo da série e vamos começar a construção do nosso quadro de trabalho.

Estarei utilizando o Visual Studio 2010 o que não impede que o mesmo seja feita em outras versões como o 2008 e 2005.

Utilizando a mesmo aplicação do primeiro artigo da série(link do artigo 1), adicione um novo projeto clicando com o botão direito na solução no menu Add > New Project > Class Library e atribua o nome GenericFrameWork conforme a figura 1.

Neste projeto iremos criar nosso Acesso a Dados Genérico e todas as classes utilitárias que considerarmos importantes para nossas aplicações.

Vamos considerar inicialmente que construiremos um framework voltado para web com acesso a dados, criptografia de informações, envio de email e uso de Java script para mensagens. Sendo assim, vamos para a construção lógica de nossa aplicação.

Se analisarmos o projeto pensando na segurança da aplicação como um todo, logo chegaremos à conclusão que algumas informações não podem ser conhecidas para não comprometer a segurança dos dados, como por exemplo, nossa string de conexão ou senhas para acesso ao sistema.

Sendo assim nossa primeira classe será para criptografia de dados. Adicione uma nova pasta ao projeto por nome Security e nesta pasta iremos acrescentar uma classe por nome Criptografia. Sua solução deve ficar como na figura 2.

            O próximo passo será alterar o namespace de nossa classe por GenericFrameWork.

            Notem que devemos declarar duas namespaces: System.Security.Cryptography e System.IO, para que esta classe possa ser compilada com sucesso. O código fonte completo segue na listagem 1.

// import namespace

using System.Security.Cryptography;

using System.IO;

namespace GenericFrameWork

{

    /// <summary>

    /// Classe de Segurança para Criptografia e Descriptografia de dados.

    /// </summary>

    public static class Criptografia

    {

        // Chave secreta a ser usada pelo algoritmo simétrico.

        private static byte[] chave = {31, 178, 32, 154, 33, 194, 34, 204, 35, 221, 36, 230,

                                                                       249, 254, 91, 117, 37, 208, 38, 185, 39, 104, 40, 201};

        // Vetor de inicialização.

        private static byte[] iv = { 6, 238, 7, 152, 8, 152, 9, 128 };

        /// <summary>

        ///     Método responsável por Criptografar um valor passado como parâmetro.

        /// </summary>

        /// <param name="valorDesCriptografado">Valor a ser criptografado.</param>

        /// <returns>Valor criptografado.</returns>

        public static string criptografar(string valorDesCriptografado)

        {

            // Verifico se foi informado um valor para criptografia.

            if (valorDesCriptografado != String.Empty)

            {

                // Vetor de bytes com a string informada.

                byte[] valor = Encoding.Unicode.GetBytes(valorDesCriptografado);

                //Crio um algoritimo simétrico utilizando a implementação TripleDESCryptoServiceProvider.

                SymmetricAlgorithm algoritmoSimetrico = new TripleDESCryptoServiceProvider();

                // ICryptoTransform=Interface que define as operações básicas de criptografia.

                // Substituo o membro CreateDecryptor da classe SymmetricAlgorithm.

                ICryptoTransform ct = algoritmoSimetrico.CreateEncryptor(chave, iv);

                // Crio um MemoryStream que encapsula dados armazenados como uma matriz de bytes.

                MemoryStream fluxoMemoria = new MemoryStream();

                // Define um fluxo que transmite dados para transformações de criptografia.

                CryptoStream fluxoCriptografia = new CryptoStream(fluxoMemoria, ct, CryptoStreamMode.Write);

                // Caso ocorra alguma exceção o objeto CryptoStream não poderá ser fechado,

                //por isso, utilizo o bloco try/catch para garantir que o objeto será fechado.

                try

                {

                    fluxoCriptografia.Write(valor, 0, valor.Length);

                    fluxoCriptografia.FlushFinalBlock();

                    // Fecho o objeto CryptoStream explicitamente para liberar o fluxo.

                    fluxoCriptografia.Close();                   

                }

                catch

                {

                    // Garanto que o objeto será fechado caso ocorra alguma exceção.

                    fluxoCriptografia.Close();

                }

                // Retorno o valor criptografado.

                return Convert.ToBase64String(fluxoMemoria.ToArray());

            }

            else

            {

                // Retorno uma string vazia.

                return String.Empty;

            }

        }

        /// <summary>

        ///     Método responsável por Descriptografar um valor passado como parâmetro.

        /// </summary>

        /// <param name="valorCriptografado">Valor a ser Descriptografado.</param>

        /// <returns>Valor Descriptografado.</returns>

        public static string decriptografar(string valorCriptografado)

        {

            // Vetor de bytes com a string informada.

            byte[] valor = Convert.FromBase64String(valorCriptografado);

            //Crio um algoritimo simétrico utilizando a implementação TripleDESCryptoServiceProvider.

            SymmetricAlgorithm algoritmoSimetrico = new TripleDESCryptoServiceProvider();

            // Substituo o membro CreateDecryptor da classe SymmetricAlgorithm.

            ICryptoTransform ct = algoritmoSimetrico.CreateDecryptor(chave, iv);

            MemoryStream fluxoMemoria = new MemoryStream();

            CryptoStream fluxoCriptografia = new CryptoStream(fluxoMemoria, ct, CryptoStreamMode.Write);

            try

            {

                fluxoCriptografia.Write(valor, 0, valor.Length);

                fluxoCriptografia.FlushFinalBlock();

                fluxoCriptografia.Close();

            }

            catch

            {

                fluxoCriptografia.Close();

            }

            // Retorno o valor descriptografado.

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

        }

    }

}

Listagem 1.

           

Algumas observações importantes:

* Para utilizar a classe SymmetricAlgorithm requer uma chave e um vetor de inicialização para executar transformações de criptografia em dados.

* A chave informada foi aleatória devendo ser substituída posteriormente por uma de sua escolha.

* RijndaelManaged, DESCryptoServiceProvider, RC2CryptoServiceProvidere e TripleDESCryptoServiceProvider(que usamos neste artigo), são implementações de algoritmos simétricos.

* Quando você herdar da classe SymmetricAlgorithm, deve-se substituir os seguintes membros: CreateDecryptor, CreateEncryptor, GenerateIV, and GenerateKey.

Pessoal, o código está bem documentado e sintam-se a vontade para utilizar outras ou suas próprias soluções de criptografia.

No próximo artigo iremos aplicar o padrão Singleton para trabalharmos com a conexão com o Banco de Dados em nossa aplicação.

Um abraço e qualquer dúvida podem mandar por email.

vitormeriat@gmail.com

http://twitter.com/vitormeriat

Até a próxima!!!

“A sorte favorece as mentes bem trabalhadas...”

Vitor Meriat

Vitor Meriat - Cusando a faculdade de Bacharel em Sistemas da Informação, programador .NET há dois anos, trabalha atualmente na Corretora Seguros BRB em Brasília com a plataforma .Net e Arquitetura da Informação.