.NET

27 fev, 2017

Criptografia na plataforma .NET

Publicidade

As técnicas usadas na criptografia podem ser divididas em quatro categorias, e, em cada uma delas, um determinado número de algoritmos é implementado na plataforma .NET usando um modelo de provedor herdado.

Para cada categoria, existe uma classe abstrata que fornece a funcionalidade comum e os provedores específicos implementam os detalhes do algoritmo.

Assim, as técnicas de criptografia podem ser divididas em:

  1. Hashing ou funções de Hash;
  2. Criptografia de chave simétrica ou privada (chave secreta);
  3. Criptografia de chave assimétrica ou pública (chave pública);
  4. Signing ou assinatura digital.

Vejamos, a seguir, cada uma destas técnicas:

Hashing ou funções de Hash

Para alcançar o objetivo da integridade dos dados, um algoritmo de hashing ou função de hash pode ser aplicado aos dados que estão sendo transmitidos. Essa operação vai gerar uma sequência de bytes que possui um tamanho fixo, que é conhecido como hash value ou valor de hash.

Para garantir a integridade dos dados, o valor do hash tem que ser único e o algoritmo deverá sempre produzir o mesmo valor de hash para os mesmos dados transmitidos.

A criptografia hash é conhecida também como hash code ou message-digest. Esse tipo de criptografia não utiliza nenhuma chave criptográfica e é irreversível, ou seja, ao ser criptografada, a mensagem não pode ser decodificada para sua forma original.

A figura abaixo exibe o processo de aplicar um algoritmo de hash:

Cenário:

  1. Maria precisa enviar uma informação para José;
  2. Maria aplica uma algoritmo de hash ao texto da informação a ser enviada e envia a informação e o hash gerado a José;
  3. José recebe a informação e verifica a sua integridade gerando um hash e comparando com o hash enviado por Maria;
  4. Se os valores dos hash forem iguais, os dados não foram modificados e são íntegros.

Nota: O valor de hash recebido não pode ser convertido para a informação original.

Observe que o processo não protege a informação de ser interceptada e facilmente lida. Além disso, não estamos garantindo que a informação recebida por José foi realmente enviada por Maria, visto que alguém poderia ter usado o mesmo algoritmo de hash antes de enviar a informação para José.

Os algoritmos de Hashing inclusos na plataforma .NET são:

  • HMACSHA1
  • MACTripleDES
  • MD5CryptoServiceProvider
  • SHA1Managed
  • SHA256Managed
  • SHA384Managed
  • SHA512Managed
  • RIPEMD-160

Vamos, agora, a um exemplo que mostra uma utilização do processo de hashing.

Autenticação de usuário com senha

No processo de autenticação de um usuário usando uma senha podemos aplicar as funções de hash.

Funciona assim:

  • Quando a conta do usuário é criada, ele fornece um nome e uma senha;
  • Ao invés de armazenar a o texto da senha, aplicamos um algoritmo de hash e geramos um valor de hash que é armazenado;
  • Quando o usuário for realizar o login para se autenticar, ele fornece o nome a a senha;
  • Então, aplicamos o mesmo algoritmo de hashing ao texto da senha que é transmitida;
  • O valor do hash gerado é comparado com o valor do hash da senha armazenada;
  • Apenas se os valores forem iguais, então, o usuário é autenticado.

Para incrementar ainda mais a segurança, podemos usar um valor aleatório (conhecido como sal) como uma entrada adicional junto a uma senha, ou algo semelhante em uma “função de mão única”, que gera como saída um hash.

A função primária do sal(salt) é defender contra ataques de dicionário aliados à aplicação da função hash nesta lista.

Implementando o hash usando o algoritmo MD5

Vamos usar o algoritmo de hash MD5 para implementar o nosso cenário. Este algoritmo é um dos mais usados para realizar o hash.

O algoritmo MD5 é uma função de hash amplamente usada que produz um valor de hash de 128 bits(16-byte), o qual é expresso no formato texto como um número hexadecimal de 32-dígitos ou como uma string codificada Base-64.

A classe MD5 é uma classe abstrata, que é responsável por fornecer a funcionalidade de hash usada pelo algoritmo MD5. Ela usa uma chave hash de 128 bits e é estendida pela classe MD5CryptoServiceProvider, que também é conhecida como classe CSP.

Para ter acesso à classe MD5CryptoServiceProvider, devemos usar o namespace System.Security.Criptography que fornece serviços criptográficos, incluindo a codificação e decodificação de dados, bem como muitas outras operações, como hash, geração de números aleatórios e autenticação de mensagem.

Vamos criar uma aplicação do tipo Console usando o Visual Studio Community 2015 e criar uma classe chamada TrataHash.

Abaixo, vemos o código implementado na classe TrataHash, onde temos:

  • O método GeraMD5Hash – gera um hash usando o algoritmo MD5;
  • O método VerificaMD5Hash – verifica o hash gerado para o texto informado com o hash original.
using System;
using System.Security.Cryptography;
using System.Text;
   public class TrataHash
    {
        public static string GeraMD5Hash(string texto)
        {
            //cria instância da classe MD5CryptoServiceProvider
            MD5CryptoServiceProvider MD5provider = new MD5CryptoServiceProvider();
            //gera o hash do texto
            byte[] valorHash = MD5provider.ComputeHash(Encoding.Default.GetBytes(texto));
            StringBuilder str = new StringBuilder();
            //retorna o hash
            for (int contador = 0; contador < valorHash.Length; contador++)
            {
                str.Append(valorHash[contador].ToString("x2"));
            }
            return str.ToString();
        }
        static bool VerificaMD5Hash(string texto, string valorHashArmazenado)
        {
            //gera o hash para o texto
            string valorHash2 = GeraMD5Hash(texto);
            // Cria um StringComparer e compara o hash gerado com o armazenado
            StringComparer strcomparer = StringComparer.OrdinalIgnoreCase;
            //se o valor dos hash forem iguais então retorna true
            if (strcomparer.Compare(valorHash2, valorHashArmazenado).Equals(0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

Para testar a nossa implementação, inclua o código abaixo no método Main() da classe Program:

 using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Informe a Senha: ");
            string senha = Console.ReadLine();
            string strValorHash = TrataHash.GeraMD5Hash(senha);
            Console.WriteLine("O Hash gerado para a senha é : " + strValorHash);
            Console.WriteLine("\nDeseja verificar o hash da senha ? Pression 'S' para verificar.");
            char ch = Convert.ToChar(Console.ReadLine());
            if (ch == 'S' || ch == 's')
            {
                Console.WriteLine("\nInforme novamente a senha: ");
                string senha2 = Console.ReadLine();
                bool resposta = TrataHash.VerificaMD5Hash(senha2, strValorHash);
                Console.WriteLine("--------------------");
                if (resposta)
                {
                    Console.WriteLine("\nO valor do HASH Confere...");
                }
                else
                {
                    Console.WriteLine("\nO valor do HASH não Confere.");
                }
                Console.WriteLine("--------------------");
                Console.ReadKey();
            }
            else { Environment.Exit(1); }
        }
    }

Podemos ver o resultado exibido na figura ao lado do código.

Pegue o projeto completo com as implementações feitas em CSharp e VB .NET aqui: CriptoGrafia_Aula2.zip.

Na próxima aula, vamos continuar a ver as demais técnicas de criptografia.