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.
* 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.

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