Imports System
Imports System.IO
Imports System.Security.Cryptography
Public Class HMACSHA256example
' Computes a keyed hash for a source file, creates a target file with the keyed hash
' prepended to the contents of the source file, then decrypts the file and compares
' the source and the decrypted files.
Public Shared Sub EncodeFile(ByVal key() As Byte, ByVal sourceFile As String, ByVal destFile As String)
' Initialize the keyed hash object.
Dim myhmacsha256 As New HMACSHA256(key)
Dim inStream As New FileStream(sourceFile, FileMode.Open)
Dim outStream As New FileStream(destFile, FileMode.Create)
' Compute the hash of the input file.
Dim hashValue As Byte() = myhmacsha256.ComputeHash(inStream)
' Reset inStream to the beginning of the file.
inStream.Position = 0
' Write the computed hash value to the output file.
outStream.Write(hashValue, 0, hashValue.Length)
' Copy the contents of the sourceFile to the destFile.
Dim bytesRead As Integer
' read 1K at a time
Dim buffer(1023) As Byte
Do
' Read from the wrapping CryptoStream.
bytesRead = inStream.Read(buffer, 0, 1024)
outStream.Write(buffer, 0, bytesRead)
Loop While bytesRead > 0
myhmacsha256.Clear()
' Close the streams
inStream.Close()
outStream.Close()
Return
End Sub
' Decrypt the encoded file and compare to original file.
Public Shared Function DecodeFile(ByVal key() As Byte, ByVal sourceFile As String) As Boolean
' Initialize the keyed hash object.
Dim hmacsha256 As New HMACSHA256(key)
' Create an array to hold the keyed hash value read from the file.
Dim storedHash(hmacsha256.HashSize / 8) As Byte
' Create a FileStream for the source file.
Dim inStream As New FileStream(sourceFile, FileMode.Open)
' Read in the storedHash.
inStream.Read(storedHash, 0, storedHash.Length)
' Compute the hash of the remaining contents of the file.
' The stream is properly positioned at the beginning of the content,
' immediately after the stored hash value.
Dim computedHash As Byte() = hmacsha256.ComputeHash(inStream)
' compare the computed hash with the stored value
Dim i As Integer
For i = 0 To storedHash.Length
If computedHash(i) <> storedHash(i) Then
Console.WriteLine("Hash values differ! Encoded file has been tampered with!")
Return False
End If
Next i
Console.WriteLine("Hash values agree -- no tampering occurred.")
Return True
End Function
Private Const usageText As String = "Usage: HMACSHA256 inputfile.txt encryptedfile.hsh" + vbLf + "You must specify the two file names. Only the first file must exist." + vbLf
Public Shared Sub Main(ByVal Fileargs() As String)
'If no file names are specified, write usage text.
If Fileargs.Length < 2 Then
Console.WriteLine(usageText)
Else
Try
' Create a random key using a random number generator. This would be the
' secret key shared by sender and receiver.
Dim secretkey() As Byte = New [Byte](63) {}
'RNGCryptoServiceProvider is an implementation of a random number generator.
Dim rng As New RNGCryptoServiceProvider()
' The array is now filled with cryptographically strong random bytes.
rng.GetBytes(secretkey)
' Use the secret key to encode the message file.
EncodeFile(secretkey, Fileargs(0), Fileargs(1))
' Take the encoded file and decode
DecodeFile(secretkey, Fileargs(1))
Catch e As IOException
Console.WriteLine("Error: File not found", e)
End Try
End If
End Sub
End Class