VB .NET - Calculando o CRC32 (MDA5 e SHA-1) de Arquivos


 Hoje temos uma dica básica usando a linguagem VB .NET que mostra como calcular o CRC32 para arquivos e o Hash  usando os algoritmos MD5 e SHA1.

 

Você já deve ter notado que alguns sites exibem os valores do checksum de seus arquivos na seção de download destes arquivos.

 

Já se perguntou o porquê disso ?

 

De forma simples, isso é feito para verificar que o arquivo que você baixou do site oficial é realmente o mesmo arquivo que você recebeu e que ele não foi modificado durante o processo de download.

 

O Checksum ou soma de verificação é um código usado para verificar a integridade de dados transmitidos através de um canal com ruídos ou armazenados em algum meio por algum tempo.

Isto é feito calculando a soma de verificação dos dados antes do envio ou do armazenamento deles, e recalculá-los ao recebê-los ou recuperá-los do armazenamento.

 

Se o valor obtido é o mesmo, as informações não sofreram alterações e portanto não estão corrompidas.

Formas mais simplificadas destas somas são vulneráveis por não detectarem algumas formas de falha. A simples soma dos valores dos caracteres por exemplo é vulnerável à troca de ordem dos mesmos pela comutatividade da soma.

Há formas mais elaboradas de se calcular estas somas que resolvem estes problemas, como por exemplo, o Cyclic Redundancy Check (verificação de redundância cíclica) ou CRC muito utilizados para detecção de falha através da divisão de polinômios.
 

Estas funções podem facilmente detectar falhas acidentais, porém caso a integridade dos dados seja uma questão de segurança, uma função mais elaborada ainda é necessária.

 

As funções de Hash criptográfico ou resumo criptográfico como o MD511 ou as da família SHA12 são adotadas nestes casos.

 

fonte : http://pt.wikipedia.org/wiki/Soma_de_verifica%C3%A7%C3%A3o

 

O algoritmo CRC (soma de verificação de redundância cíclica) é uma maneira altamente otimizada e poderosa de verificar se um grande número de bytes foram modificados ou não.

O algoritmo percorre todos os bytes e gera um número de 32 bits para representar o conteúdo, dessa forma, pequenas mudanças no conteúdo do arquivo irão resultar em grandes alterações na soma de verificação, e, há uma possibilidade muito baixa que dois streams diferentes de bytes tenham o mesmo valor de CRC.
 

O algoritmo CRC32 é uma maneira confiável de verificar se ocorreu um erro em uma seqüência de bytes. Existem vários meios de verificar se nenhum byte foi danificado, por exemplo, somas de controle e bits de paridade, mas muitos esquemas simples executam com uma grande chance de não detectar um erro, dependendo do tipo de corrupção que ocorre nos dados.

Com CRC as chances de ocorrer uma corrupção o que resultaria em um mesmo valor de CRC são extremamente remotas.

 

Para realizar o checksum eu vou usar uma classe chamada CRC32 obtida na internet (link : wpsjr1@succeed.net) e os recursos do namespace System.Security.Cryptography.

 

Recursos Usados:

Criando o projeto no Visual Studio Express 2013

Abra o Visual Studio Express 2013 for windows desktop e clique em New Project;

A seguir selecione a linguagem Visual Basic e o template Windows Forms informando o nome Calculando_CheckSum.

Será criado um projeto com um formulário form1.vb. Vamos incluir a partir da ToolBox os seguintes controles no formulário:

Disponha os controles conforme o leiaute da figura abaixo:

 

 

Funciona assim:

 

O usuário informa o local e nome do arquivo para o qual deseja calcular o CRC e clique no botão de comando - Calcular Hash.

 

Usamos a classe CRC32 para calcular o CheckSum e a classe HiResTimer para calcular o tempo de processamento.

 

Vamos calcular também o Hash usando os algoritmos MD5 e SHA1.

Os algoritmos de hashing, são métodos de processamento que toma uma parte do conteúdo original e gera um valor condensado representando o conteúdo completo.

Um hash é uma seqüência de letras ou números geradas por um algoritmo de dispersão.

Essa seqüência busca identificar um arquivo ou informação unicamente. Por exemplo, uma mensagem de correio eletrônico, uma senha, uma chave criptográfica ou mesmo um arquivo. É um método para transformar dados de tal forma que o resultado seja (quase) exclusivo. Além disso, funções usadas em criptografia garantem que não é possível a partir de um valor de hash retornar à informação original.

Como a seqüência do hash é limitada, muitas vezes não passando de 512 bytes, existem diversas colisões (seqüências iguais para dados diferentes). Quanto maior for a dificuldade de se criar colisões intencionais, melhor é o algoritmo.

Uma função de hash recebe um valor de um determinado tipo e retorna um código para ele. Enquanto o ideal seria gerar identificadores únicos para os valores de entrada, isso normalmente não é possível: na maioria dos casos, o contra-domínio de nossa função é muito menor do que o seu domínio, ou seja, x (o tipo de entrada) pode assumir uma gama muito maior de valores do que hash(x) (o resultado da função de hash).

Os mais usados algoritmos de hash são os 16 bytes: MD2, MD4, MD5 ou o SHA-1, de 20 bytes. Características de alguns algoritmos:

  1. MD4: Desenvolvido em 1990/91 por Ron Rivest, vários ataques foram detectados, o que fez com que o algoritmo fosse considerado frágil.
  2. SHA-1 (Secure Hash Algorithm): Desenvolvido pelo NIST e NSA e é considerado como o mais seguro atualmente. 
    fonte - Wikipédia - http://pt.wikipedia.org/wiki/Hash

 

 

Implementando o código

 

Os namespaces usados no projeto e declarados no início do formulário form1.vb são:

 

Imports System.IO

Imports System.Security.Cryptography
Imports System.Text

 

No evento Click do botão - btnProcurar - temos o código que abre a caixa de diálogo para selecionar um arquivo. Definimos a pasta inicial com sendo c:\dados.

 

Private Sub btnProcurar_Click(sender As Object, e As EventArgs) Handles btnProcurar.Click

        Dim o As OpenFileDialog = New OpenFileDialog()
        o.InitialDirectory = "C:\dados"
        o.Filter = "Todos (*.*)|*.*"

        If (o.ShowDialog() = DialogResult.OK) Then
            txtNomeArquivo.Text = o.FileName
        End If

End Sub

 

No evento TextChanged da caixa de texto txtNomeArquivo incluímos o código que habilita a caixa de texto após algo ser digitado:

 

 Private Sub txtNomeArquivo_TextChanged(sender As Object, e As EventArgs) Handles txtNomeArquivo.TextChanged
        Dim testPath As String = txtNomeArquivo.Text
        btnGerarHash.Enabled = File.Exists(testPath)
    End Sub

 

Código do evento Click do botão de comando que irá calcular o CRC:

 

Private Sub btnGerarHash_Click(sender As Object, e As EventArgs) Handles btnGerarHash.Click
        Try
            Dim c As New CRC32()
            Dim crc As Integer = 0
            Dim h As HiResTimer = New HiResTimer()
            Console.WriteLine("{0} {1}", h.HasHiResCounter, h.Frequency)
            ' CRC32 Hash:
            h.StartTimer()
            Dim f As FileStream = New FileStream(txtNomeArquivo.Text, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
            crc = c.GetCrc32(f)
            f.Close()
            h.StopTimer()
            ' tamanho do arquivo
            f = New FileStream(txtNomeArquivo.Text, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
            txtTamanho.Text = String.Format("{0}", f.Length)
            f.Close()
            txtCrc32.Text = String.Format("{0:X8}", crc)
            txtTempo.Text = String.Format("{0}", h.ElapsedTime)
            ' Calcula o Hash MD5
            h = New HiResTimer()
            h.StartTimer()
            f = New FileStream(txtNomeArquivo.Text, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
            Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
            md5.ComputeHash(f)
            f.Close()
            h.StopTimer()
            Dim hash As Byte() = md5.Hash
            Dim buff As StringBuilder = New StringBuilder()
            Dim hashByte As Byte
            For Each hashByte In hash
                buff.Append(String.Format("{0:X1}", hashByte))
            Next
            txtMD5.Text = buff.ToString()
            txtMD5Tempo.Text = String.Format("{0}", h.ElapsedTime)
            ' Calcula o Hash SHA-1
            h = New HiResTimer()
            h.StartTimer()
            f = New FileStream(txtNomeArquivo.Text, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
            Dim sha1 As SHA1CryptoServiceProvider = New SHA1CryptoServiceProvider()
            sha1.ComputeHash(f)
            f.Close()
            h.StopTimer()
            hash = sha1.Hash
            buff = New StringBuilder()
            For Each hashByte In hash
                buff.Append(String.Format("{0:X1}", hashByte))
            Next
            txtSHA1.Text = buff.ToString()
            txtSHA1Tempo.Text = String.Format("{0}", h.ElapsedTime)
        Catch ex As Exception
            MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

 

 

Este código utiliza as seguintes métodos :

  1. Cálculo do Hash via CRC32 (usa a classe CRC32)

  2. Cálculo do Hash via MD5

  3. Cálculo do Hash via SHA1

Executando o projeto e informando um recurso a excluir obtemos o seguinte resultado:

 

 

Pegue projeto completo aqui:  Calculando_Checksum.zip

 

Em tudo somos atribulados, mas não angustiados; perplexos, mas não desanimados.
Perseguidos, mas não desamparados; abatidos, mas não destruídos;
Trazendo sempre por toda a parte a mortificação do Senhor Jesus no nosso corpo, para que a vida de Jesus se manifeste também nos nossos corpos;

2 Coríntios 4:8-10

 

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti