Uma aplicação ou sistema tem inúmeras funcionalidades, no entanto, existe uma funcionalidade que geralmente ocorre nos bastidores, ou seja, no backend da aplicação e não é de conhecimento dos usuários do sistema: estamos falando da Criptografia de Dados.

Com a evolução dos sistemas e cada vez mais se optando pelo tipo on-line, é necessário se preocupar com a segurança das informações do seu sistema, então veremos como implementar Criptografia no Silverlight.

O assunto Criptografia é muito extenso, pois existem inúmeros algoritmos no mercado como criptografia simétrica, criptografia assimétrica, hash e assinaturas digitais.

Neste artigo iremos ver como implementar uma criptografia Simétrica em c#. Este tipo de criptografia é uma das mais básicas e também mais rápida, pois a mesma chave é utilizada para criptografar e descriptografar dados.

As chaves usadas geralmente são menores que 256 bits, motivo este delas serem relativamente pequenas é para não onerar o processo, ou seja, quanto maior a chave utilizada, mais recurso de processamento será necessário para criptografar e descriptografar dados.

Exemplos de algoritmos de criptografia simétrica:

  1. O DES ("Data Encryption Standard") - é um mecanismo de cifragem tradicional (simétrico) desenvolvido nos anos setenta e utiliza uma chave de 56 bits que é aplicada a blocos de dados com 64 bits com o objetivo de dificultar o cálculo da chave K, mesmo conhecendo o algoritmo DES. Uma mensagem cifrada C e uma mensagem original M: C = DES(K,M);
  2. Rivest Ciphers (RC2; RC4 e RC5) - Esta é uma sucessão de algoritmos bastante usados que possuem maior flexibilidade e possibilitam maior segurança do que o DES simples. Todos são algoritmos simétricos, ou seja, a mesma chave é usada para cifrar e para decifrar;
  3. International Data Encryption Algorithm (IDEA) - É mais uma técnica de cifragem simétrica em bloco que é usada nos dias atuais. Usa blocos fixos com 64 bits (8 bytes) e usa chaves com 128 bits (16 bytes). É considerada segura, mas ao contrário dos algoritmos RC, usa chaves de comprimento fixo que podem comprometer segurança;
  4. BLOWFISH - É um algoritmo simétrico conhecido pela sua velocidade, sendo mais rápido do que o RC2 e o IDEA. Usa blocos fixos com 64 bits (8 bytes), mas as chaves podem ter qualquer comprimento (128 bits é o mais usado);
  5. ARCFOUR - É um algoritmo considerado equivalente ao RC4, pois não usa blocos de entrada, mas sim um fluxo contínuo de bytes e as chaves podem ter comprimento variável (128 bits é o mais usado);
  6. Advanced Encryption Standard(AES) - ou Padrão de Criptografia Avançada é uma cifra de bloco adotada como padrão de criptografia pelo governo dos Estados Unidos. É atualmente o algoritmo simétrico mais usado. O AES foi anunciado pelo NIST (Instituto Nacional de Padrões e Tecnologia dos EUA) como U.S. FIPS PUB (FIPS 197) em 26 de Novembro de 2001, depois de cinco anos de um processo de padronização. Tornou-se um padrão efetivo em 26 de Maio de 2002.

Neste artigo iremos utilizar o algoritmo AES que já esta contido na Classe System.Security.Cryptograph do .NET. Para isso, abram o Visual Studio 2012 e acesse o menu Arquivo(File) -> Novo (New) -> Projeto (Project), conforme a Figura 1.

Iniciando Novo
projeto

Figura 1. Iniciando Novo projeto.

Na janela Seguinte digite “Branco” (Empty) na caixa de pesquisa, selecione Solução em Branco (Blank Solution) e altere a propriedade Nome (name) para SLCRYPTOGRAPH ou para o nome que preferir, conforme ilustrado na Figura 2.

Criando uma Solução

Figura 2. Criando uma Solução.

Se olharmos no Gerenciador de Soluções (Solution Explorer) veremos que foi criada uma solução vazia. Então agora clique com o botão direito do mouse e escolha Adicionar e em seguida Novo Projeto. Selecione a opção Silverlight Class Library e dê o nome de Cryptograph, pois esse será nosso projeto que conterá a Classe de Criptografar e descriptografar. Veja os passos nas Figuras 3 e 4.

Adicionando um
Projeto a Solução

Figura 3. Adicionando um Projeto a Solução.

Selecionando Projeto
Silverlight Class Library

Figura 4. Selecionando Projeto Silverlight Class Library.

Ao adicionar o projeto Silverlight Class Library, o Visual Studio exibirá uma caixa de diálogo para que você escolha a versão do Silverlight: opte pelo Silverlight 5. Caso não tenha, pode ser o Silverlight 4, mas na versão 3 pode não funcionar corretamente. Observe a Figura 5.

Escolhendo a Versão
do Silverlight

Figura 5. Escolhendo a Versão do Silverlight.

Acesse o Gerenciador de Soluções, clique com o botão direito do Mouse no arquivo Class1.cs e altere o nome para Crypto. Será exibida uma mensagem perguntando se você deseja que seja alterado o nome da Classe também; clique em Sim. Com isso o Visual Studio já irá alterar o nome da classe. Veja os passos nas Figuras 6 e 7.

Renomeando o Arquivo
Class1 para Crypto

Figura 6. Renomeando o Arquivo Class1 para Crypto.

Mensagem de
alteração da Classe

Figura 7. Mensagem de alteração da Classe.

Antes de iniciarmos a implementação de nossa classe devemos inserir as using’s System.IO, System.Security.Cryptograph e System.Windows.Input, conforme mostrado na Listagem 1.

Listagem 1. Declarando as using’s da classe Crypto.


  using System;
  using System.IO;
  using System.Security.Cryptography;
  using System.Windows.Input;
  

Como sabemos, para criptografar alguma coisa precisamos de uma palavra chave, então vamos iniciar nossa classe criando três propriedades privadas que serão nossa Chave, nosso Vetor de Inicialização (para criptografia que vamos implementar é obrigatório a criação desse vetor) e nosso Salt, que é um array de byte que será responsável pela geração de chaves quando você não quiser utilizar a chave padrão. Veja na Listagem 2.

Listagem 2. Declaração das propriedades privadas.


   private byte[] Key ;
          private byte[] IV ={ 0x50, 0x08, 0xF1, 0xDD, 0xDE, 0x3C, 0xF2, 0x18, 0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC };
          private byte[] salt = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0 };
  

Feito isso, nossa classe precisará de dois construtores: um que não receberá parâmetro nenhum e servirá para inicializarmos nossa Key com o valor padrão e o outro construtor deverá receber uma string e a implementaremos para que ele utilize essa string para gerar uma chave para nossa criptografia. Veja Listagem 3.

Listagem 3. Construtores da Classe Crypto.


          public Crypto()
          {
              Key = Convert.FromBase64String("Q3JpcHRvZ3JhZmlhcyBjb20gUmluamRhZWwgLyBBRVM=");            
          }
   
          public Crypto(string _Key)
          {
              Rfc2898DeriveBytes chave = new Rfc2898DeriveBytes(_Key, salt);
   
              Key = chave.GetBytes(16);
          }
  

Na listagem acima criamos um construtor sem parâmetro é setamos nossa propriedade Key convertendo uma chave padrão string para Base64. No segundo construtor é exigido um parâmetro do tipo string que é para que você possa criar suas próprias chaves. No entanto, para que seja criada uma chave correta no formato base64 precisamos do auxílio da classe Rfc2898DeriveBytes. Com isso, qualquer string passada como parâmetro será convertida em uma chave válida.

Agora iremos implementar dois métodos na nossa Classe: o método Encryptograph_Aes receberá uma string e retornará uma string Criptografada, e o método Decryptograph_Aes que também receberá uma string criptografada e retornará a mesma descriptografada. Para isso, implemente as Listagens 4 e 5.

Listagem 4. Método de Criptografar String.


          public string Encryptograph_Aes(string plainText)
          {
              // Check arguments. 
              if (plainText == null || plainText.Length <= 0)
                  throw new ArgumentNullException("plainText");
              if (Key == null || Key.Length <= 0)
                  throw new ArgumentNullException("Key");
              if (IV == null || IV.Length <= 0)
                  throw new ArgumentNullException("Key");
              byte[] encrypted;
              
              byte[] bKey = Key;
   
              using (AesManaged aesAlg = new AesManaged())
              {
                  aesAlg.Key = bKey;
                  aesAlg.IV = IV;
   
                  // Create a decrytor to perform the stream transform.
                  ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
   
                  // Create the streams used for encryption. 
                  using (MemoryStream msEncrypt = new MemoryStream())
                  {
                      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                      {
                          using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                          {
   
                              //Write all data to the stream.
                              swEncrypt.Write(plainText);
                          }
                          encrypted =  msEncrypt.ToArray();
                      }
                  }
              }
   
              return Convert.ToBase64String(encrypted);
   
          }
   

Listagem 5. Método de Decriptograr String.


    public string Decryptograph_Aes(string plainText)
          {
              // Check arguments. 
              if (plainText == null || plainText.Length <= 0)
                  throw new ArgumentNullException("plainText");
              if (Key == null || Key.Length <= 0)
                  throw new ArgumentNullException("Key");
              if (IV == null || IV.Length <= 0)
                  throw new ArgumentNullException("Key");
   
              byte[] cipherText = Convert.FromBase64String(plainText);
   
              byte[] bKey = Key;
   
              // Create an AesManaged object 
              // with the specified key and IV. 
              using (AesManaged aesAlg = new AesManaged())
              {
                  aesAlg.Key = bKey;
                  aesAlg.IV = IV;
   
                  // Create a decrytor to perform the stream transform.
                  ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
   
                  // Create the streams used for decryption. 
                  using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                  {
                      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                      {
                          using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                          {
   
                              // Read the decrypted bytes from the decrypting stream 
                              // and place them in a string.
                              plainText = srDecrypt.ReadToEnd();
                          }
                      }
                  }
   
              }
   
              return plainText;
   
          }
  

Na implementação acima, tanto para Criptografar quanto para descriptografar recebemos como parâmetro uma string e convertemos para um valor Base64. Realizamos toda a criptografia/descriptografia e novamente convertemos para String para poder retorna no método.

Com isso, terminamos a implementação da nossa classe. Então agora acesse o Gerenciador de Soluções, clique com o botão direito do mouse sobre a nossa solução e escolha Adicionar -> Novo Projeto. Na nova Janela escolha Silverlight Application e altere a propriedade Nome para SilverCrypto. Nas Figuras 8 e 9 temos as ilustrações do processo.

Adicionando um novo
projeto Silverlight

Figura 8. Adicionando um novo projeto Silverlight.

Adicionando projeto
Silverlight Application

Figura 9. Adicionando projeto Silverlight Application.

Na tela que irá se abrir, você deverá marcar a opção Enable WCF RIA Services e certificar que a opção Silverlight Version está como Silverlight 5, conforme a Figura 10.

Opções Silverlight

Figura 10. Opções Silverlight.

Acesse o Gerenciador de soluções e dê um duplo clique no arquivo MainPage.xaml do projeto SilverLight. Com ele aberto você deverá adicionar sete textbox, sete label e quatro button e suas propriedades deverão ser alteradas conforme mostra a Listagem 6.

Listagem 6. Código XAML – Propriedades dos componentes.


  <UserControl
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication1.MainPage"
      mc:Ignorable="d"
      d:DesignHeight="554.769" d:DesignWidth="877.615">
   
      <Grid x:Name="LayoutRoot" Background="White" Margin="20" RenderTransformOrigin="0.492,0.477">
          <TextBox Name="txtWord" HorizontalAlignment="Left" Height="21" Margin="150,25,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="349"/>
          <TextBox Name="txtCrypto" HorizontalAlignment="Left" Height="21" Margin="150,75,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="670" IsReadOnly="True"/>
          <TextBox Name="txtDeCrypto" HorizontalAlignment="Left" Height="21" Margin="150,120,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="336" IsReadOnly="True"/>
          <sdk:Label Name="lblWord" HorizontalAlignment="Left" Height="21" Margin="6,25,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Para Criptografar"/>
          <sdk:Label Name="lblWordCrypto"  HorizontalAlignment="Left" Height="21" Margin="6,76,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Criptografada"/>
          <sdk:Label Name="lblWordDeCrypto"  HorizontalAlignment="Left" Height="21" Margin="6,120,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Descriptografada"/>
          <Button Name="btnCrypto" Content="Cryptograph" HorizontalAlignment="Left" Margin="137,190,0,0" VerticalAlignment="Top" Width="75" Click="btnCrypto_Click" />
          <Button Name="btnDeCrypto" Content="Decryptograph" HorizontalAlignment="Left" Margin="264,190,0,0" VerticalAlignment="Top" Width="75" Click="btnDeCrypto_Click" />
          <TextBox x:Name="txtPass" HorizontalAlignment="Left" Height="21" Margin="150,251,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="349"/>
          <TextBox x:Name="txtWordPass" HorizontalAlignment="Left" Height="21" Margin="150,297,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="349"/>
          <TextBox x:Name="txtCryptoPass" HorizontalAlignment="Left" Height="21" Margin="150,344,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="670" IsReadOnly="True"/>
          <TextB  ox x:Name="txtDeCryptoPass" HorizontalAlignment="Left" Height="21" Margin="150,389,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="336" IsReadOnly="True"/>
          <sdk:Label Name="lblPass" HorizontalAlignment="Left" Height="21" Margin="6,251,0,0" VerticalAlignment="Top" Width="145" Content="Senha"/>
          <sdk:Label Name="lblWordPass"  HorizontalAlignment="Left" Height="21" Margin="6,297,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Para Criptografar"/>
          <sdk:Label Name="lblWordCryptoPass" HorizontalAlignment="Left" Height="21" Margin="6,345,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Criptografada"/>
          <sdk:Label Name="lblWordDeCryptoPass" HorizontalAlignment="Left" Height="21" Margin="6,389,0,0" VerticalAlignment="Top" Width="145" Content="Palavra Descriptografada"/>
          <Button Name="btnCryptoPass" Content="Cryptograph with password" HorizontalAlignment="Left" Margin="137,458,0,0" VerticalAlignment="Top" Width="202" Click="btnCryptoPass_Click" />
          <Button Name="btnDeCryptoPass" Content="Decryptograph with password" HorizontalAlignment="Left" Margin="374,458,0,0" VerticalAlignment="Top" Width="266" Click="btnDeCryptoPass_Click" />
      </Grid>
  </UserControl>
  

Após implementar o código XAML da listagem acima você deverá ter o resultado, conforme a Figura 11.

Layout Aplicativo

Figura 11. Layout Aplicativo.

Agora já temos nosso layout pronto precisamos implementar os métodos dos quatro botões para que os mesmo realizem a criptografia e descriptografia da palavra digitada.

Abaixo segue as Listagens 7, 8 e 9 com os códigos de implementação dos botões.

Listagem 7. Código do Botão btnCryptoPass.


          private void btnCryptoPass_Click(object sender, RoutedEventArgs e)
          {
              //Instanciando a classe Crypto com o Construtor que solicita a chave.
              Crypto _crypto = new Crypto(txtPass.Text);
   
              txtCryptoPass.Text = _crypto.Encryptograph_Aes(txtWordPass.Text);
          }
  

Listagem 8. Código do Botão btnDeCryptoPass.


          private void btnDeCryptoPass_Click(object sender, RoutedEventArgs e)
          {
              //Instanciando a classe Crypto com o Construtor que solicita a chave.
              Crypto _crypto = new Crypto(txtPass.Text);
   
              txtDeCryptoPass.Text = _crypto.Decryptograph_Aes(txtCryptoPass.Text);
          } 
  

Listagem 9. Código do Botão btnCrypto.


          private void btnCrypto_Click(object sender, RoutedEventArgs e)
          {
              //Instanciando a classe Crypto com o Construtor sem Parametro
              Crypto _crypto = new Crypto();
              
              txtCrypto.Text = _crypto.Encryptograph_Aes(txtWord.Text);
          } 
  

Listagem 10. Código do Botão btnDeCrypto.


          private void btnDeCrypto_Click(object sender, RoutedEventArgs e)
          {
              //Instanciando a classe Crypto com o Construtor sem Parametro
              Crypto _crypto = new Crypto();
   
              txtDeCrypto.Text = _crypto.Decryptograph_Aes(txtCrypto.Text);
          } 
  

Nas quatro listagens acima realizamos o instanciamento da nossa classe Crypto, onde em duas chamadas não passamos o parâmetro que é para utilizar a chave padrão e nas outras duas passamos como parâmetro o valor contido em um textbox que pode ser alterado pelo usuário. Com isso, mostramos que nossa classe funciona com qualquer senha criada pelo usuário.

Criamos quatro botões para que você possa ver as duas formas de implementação: uma usando a chave padrão e a outra você passa a chave desejada para que o algoritmo realize a criptografia. Na Figura 12 segue o Resultado final desse artigo.

Resultado Final

Figura 12. Resultado Final.

Concluindo, hoje existem inúmeras alternativas de algoritmos de criptografia para se implementar. O que vai dizer qual deles você deve utilizar são os seguintes fatores: tempo para implementação, Nível de Complexidade da aplicação e nível de segurança desejado. No caso da AES (Advanced Encryption Standard) é fácil notar que é uma implementação bem simples e rápida, porém, devido a ela ser uma criptografia simétrica, ou seja, onde a chave de Criptografia é idêntica a de descriptografia, e ambas tem que estar nas duas pontas, não é tão segura. Para casos como intranet ou sistemas de baixa complexidade acredito que é uma excelente forma de garantir a segurança das informações.

Ficamos por aqui com mais um artigo espero que gostem e que seja útil.

Até a próxima.