Verificare l’integrità di un file con l’algoritmo di hash

Può succedere che durante l'invio dei files in rete, questi possano essere intercettati e manipolati da utenti malintenzionati. Succede altresì che alcuni flussi di dati perdano parti delle loro informazioni durante il loro trasferimento.

Per verificare l'integrità del file trasmesso bisogna sottoporlo, prima dell'invio, ad un algoritmo di hash che ne restituisce un riassunto univoco (hash digest) sottoforma di array di byte*. Lo stesso algoritmo dovrà essere applicato anche al file di destinazione. Comparando poi i due valori hash risultanti, sarà possibile determinare se sono state apportate delle modifiche al file di destinazione, anche se minime.

image

* Per semplificare al massimo il concetto: l'hash digest è paragonabile all'ultima lettera del Codice Fiscale che serve a convalidare l'intero codice. La modifica di una sola lettera o numero del codice fiscale comporta la modifica e la relativa inesattezza dell'ultimo carattere. La modifica di un solo byte all'interno di un file comporta la modifica del valore restituito dall'algoritmo di hash.

image image

image image

Anche modificando un solo carattere all’interno di un testo, si ottengono dei compendi completamenti diversi.

E' possibile scaricare il programma da qui.

Per far funzionare il programma è necessario aver installato Microsoft .NET Framework 3.0 scaricabile da qui.

 

Il cuore dell’applicazione è questo codice:

' VB.
    ' Dichiara le variabili tipo che conterranno gli Hash.
    Dim hashOriginalMD5() As Byte
    Dim hashOriginalSHA1() As Byte
    Dim hashOriginalSHA384() As Byte
    Dim hashCopyMD5() As Byte
    Dim hashCopySHA1() As Byte
    Dim hashCopySHA384() As Byte

    Private Sub btnBrowse_Original_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse_Original.Click
        ' Seleziona il file originale.
        If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.txtPath_Original.Text = Me.OpenFileDialog1.FileName
            If My.Computer.FileSystem.FileExists(Me.txtPath_Original.Text) Then

                ' Legge un file e lo inserisce in un arry di byte.
                Dim fInfo As New IO.FileInfo(Me.txtPath_Original.Text)
                Dim bytes As Byte() = ConvertToByte(fInfo)

                ' Legge il codice Hash utilizzando gli algoritmi hash più comuni.
                hashOriginalMD5 = GetHash(bytes, "MD5CryptoServiceProvider")
                hashOriginalSHA1 = GetHash(bytes, "SHA1CryptoServiceProvider")
                hashOriginalSHA384 = GetHash(bytes, "SHA384CryptoServiceProvider")

                ' Imposta le etichette.
                Me.lblMD5_Original.Text = String.Format("Chiave riassuntiva MD5: {0}", Convert.ToBase64String(hashOriginalMD5))
                Me.lblSHA1_Original.Text = String.Format("Chiave riassuntiva SHA1: {0}", Convert.ToBase64String(hashOriginalSHA1))
                Me.lblSHA384_Original.Text = String.Format("Chiave riassuntiva SHA384: {0}", Convert.ToBase64String(hashOriginalSHA384))
            Else
                MessageBox.Show(String.Format("Il file {0} non esiste.", Me.txtPath_Original.Text), "File inesistente", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End If
    End Sub

    Private Sub btnBrowse_Copy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse_Copy.Click
        ' Seleziona il file originale.
        If Me.OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.txtPath_Copy.Text = Me.OpenFileDialog1.FileName
            If My.Computer.FileSystem.FileExists(Me.txtPath_Copy.Text) Then

                ' Legge un file e lo inserisce in un arry di byte.
                Dim fInfo As New IO.FileInfo(Me.txtPath_Copy.Text)
                Dim bytes As Byte() = ConvertToByte(fInfo)

                ' Legge il codice Hash utilizzando gli algoritmi hash più comuni.
                hashCopyMD5 = GetHash(bytes, "MD5CryptoServiceProvider")
                hashCopySHA1 = GetHash(bytes, "SHA1CryptoServiceProvider")
                hashCopySHA384 = GetHash(bytes, "SHA384CryptoServiceProvider")

                ' Imposta le etichette.
                Me.lblMD5_Copy.Text = String.Format("Chiave riassuntiva MD5: {0}", Convert.ToBase64String(hashCopyMD5))
                Me.lblSHA1_Copy.Text = String.Format("Chiave riassuntiva SHA1: {0}", Convert.ToBase64String(hashCopySHA1))
                Me.lblSHA384_Copy.Text = String.Format("Chiave riassuntiva SHA384: {0}", Convert.ToBase64String(hashCopySHA384))

                ' Esegue la comparazione dei due hash.
                ' In questo esempio viene utilizzato l'algoritmo hashOriginalSHA384.
                If HashCompare(hashOriginalSHA384, hashCopySHA384) Then
                    MessageBox.Show("I due file sono strutturalmente identici." & Environment.NewLine & "Si tratta del tratta del medesimo file.", "Stesso file", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Else
                    MessageBox.Show("I due file non sono strutturalmente identici." & Environment.NewLine & "Si tratta di due file diversi oppure modificati.", "File diversi", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End If
            Else
                MessageBox.Show(String.Format("Il file {0} non esiste.", Me.txtPath_Copy.Text), "File inesistente", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End If
    End Sub

    Private Function GetHash(ByVal source As Byte(), ByVal typeCrypt As String) As Byte()
        ' Decodificanda l'hash utilizzando l'algoritmo selezionato.
        Dim hash() As Byte = Nothing
        Select Case typeCrypt
            Case "MD5CryptoServiceProvider"
                Dim MD5 As New Security.Cryptography.MD5CryptoServiceProvider
                hash = MD5.ComputeHash(source)
            Case "SHA1CryptoServiceProvider"
                Dim sha1 As New Security.Cryptography.SHA1CryptoServiceProvider
                hash = sha1.ComputeHash(source)
            Case "SHA384CryptoServiceProvider"
                Dim sha384 As New Security.Cryptography.SHA384CryptoServiceProvider
                hash = sha384.ComputeHash(source)
        End Select

        ' Ritorna l'hash codificato in base all'algoritmo selezionato.
        Return hash
    End Function

    Private Function HashCompare(ByVal hashOriginal As Byte(), ByVal hashCopy() As Byte) As Boolean
        ' Compara ogni singolo byte dei due hash.
        For i As Integer = 0 To hashOriginal.Length - 1
            If hashOriginal(i) <> hashCopy(i) Then
                Return False
            End If
        Next
        Return True
    End Function

Technorati Tag:

Print | posted on sabato 21 marzo 2009 17.43

Feedback

# re: Verificare l’integrità di un file con l’algoritmo di hash

Left by Alberto at 28/03/2009 0.35
Gravatar Ottimo post. A breve pubblicherò un articolo che illustra come utilizzare l'hash per ridurre il traffico di rete verso un DataBase.
Alberto

# re: Verificare l’integrità di un file con l’algoritmo di hash

Left by Andrea at 10/04/2009 11.05
Gravatar Grazie Alberto.

Andrea

Your comment:





 
Please add 5 and 7 and type the answer here:

Copyright © Andrea Zingoni

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski