HK1 HK1 - 4 months ago 74
Vb.net Question

VB.Net Console app to return SHA512 Hash

I'm trying to write a console application in VB.Net (2008) to accept a command line argument input (a password) and output the hash. I modified the code here so that it would accept an argument and I added my own salt/key but the output appears to be incorrect when compared to PHP's output for the same password and salt.

I need something like this so I will have a way to get a SHA512 hash using MS Access VBA. Can you recommend a better solution than what I'm trying or point me to something simpler than the link above? I could possibly post my code here but it's quite long.

Edit1:
I'm using the code from Smerkin Gherkin below now but my PHP hash and my VB.Net hash still does not match. The password and salt I'm using (as a test only) on both are: Password1 abcd1234

My VB.Net code looks like this:
SHA512Hasher.HexHash("Password1", "abcd1234")

My PHP code looks like this:
echo hash_hmac("sha512", "Password1", "abcd1234");

VB.Net returns this:
4E1112E5D2995ECDBF5777BA2B5425B86164044B1564D4A2E0232F5E5BC4A4DA34E9AD8C2E5F664FE795C5ED12753B56563164F239070C45B8278F268A8A0860

PHP returns this:
46d338722b931f2e025ecaa7853da070ad74a4e648c48633388740d647f1edba7f83afe43a104d7f7e0662e130a184743caea39177bc8deda030087d9e425e09

Any ideas what I'm doing wrong?

Answer

The simplest option is to use the System.Security.Cryptography.Sha512Managed object. Below is an example that would return SHA512 hash values as base64 strings or as hex strings.

Public Class SHA512Hasher

    Private Sub New()
        ' Prevent instantiation
    End Sub

    Public Shared Function Base64Hash(ByVal clearText As String) As String
        Dim hashedBytes As Byte() = computeHash(clearText)
        Return Convert.ToBase64String(hashedBytes)
    End Function

    Public Shared Function Base64Hash(ByVal clearText As String, ByVal salt As String) As String
        Return Base64Hash(salt & clearText)
    End Function

    Public Shared Function HexHash(ByVal clearText As String) As String
        Dim hashedBytes As Byte() = computeHash(clearText)

        ' Build the hex string by converting each byte.
        Dim hexString As New System.Text.StringBuilder()
        For i As Int32 = 0 To hashedBytes.Length - 1
            hexString.Append(hashedBytes(i).ToString("X2")) ' Use "x2" for lower case
        Next

        Return hexString.ToString()
    End Function

    Public Shared Function HexHash(ByVal clearText As String, ByVal salt As String) As String
        Return HexHash(salt & clearText)
    End Function

    Private Shared Function computeHash(ByVal clearText As String) As Byte()

        Dim encoder As New Text.UTF8Encoding()
        Dim sha512hasher As New System.Security.Cryptography.SHA512Managed()
        Return sha512hasher.ComputeHash(encoder.GetBytes(clearText))

    End Function

End Class

A simple console application to print some output to the command line is

Module Module1

    Sub Main()
        Dim clear As String = "Foo"
        Dim salt As String = "Salted"

        Console.WriteLine(SHA512Hasher.Base64Hash(clear))
        Console.WriteLine(SHA512Hasher.Base64Hash(clear, salt))
        Console.WriteLine(SHA512Hasher.HexHash(clear))
        Console.WriteLine(SHA512Hasher.HexHash(clear, salt))

    End Sub

End Module

Edit1 - Updated in response to Edit1 in question

The php function hashes the value with a key which is different to salting the hash (prefixing the clear text with a salt value). The .Net object to use is System.Security.Cryptography.HMACSHA512. An update version of the above code is:

Public Class HMACSHA512Hasher

    Private Sub New()
        ' Prevent instantiation
    End Sub

    Public Shared Function Base64Hash(ByVal clearText As String) As String
        Return Base64Hash(clearText, String.Empty)
    End Function

    Public Shared Function Base64Hash(ByVal clearText As String, ByVal key As String) As String
        Dim hashedBytes As Byte() = computeHash(clearText, key)
        Return Convert.ToBase64String(hashedBytes)
    End Function

    Public Shared Function HexHash(ByVal clearText As String) As String
        Return HexHash(clearText, String.Empty)
    End Function

    Public Shared Function HexHash(ByVal clearText As String, ByVal key As String) As String
        Dim hashedBytes As Byte() = computeHash(clearText, key)

        ' Build the hex string by converting each byte.
        Dim hexString As New System.Text.StringBuilder()
        For i As Int32 = 0 To hashedBytes.Length - 1
            hexString.Append(hashedBytes(i).ToString("x2")) ' Use "x2" for lower case
        Next

        Return hexString.ToString()
    End Function

    Private Shared Function computeHash(ByVal clearText As String, ByVal key As String) As Byte()

        Dim encoder As New Text.UTF8Encoding()
        Dim sha512hasher As New System.Security.Cryptography.HMACSHA512(encoder.GetBytes(key))
        Return sha512hasher.ComputeHash(encoder.GetBytes(clearText))

    End Function

End Class

I have also changed the hex function to return lower case hash to match the php result.