VBA – Get a String’s Hash

In a previous article, I demonstrated how we could utilize PowerShell to get the MACTripleDES, MD5, RIPEMD160,  SHA1, SHA256, SHA384 or SHA512 HASH of a string

I figured I’d also demonstrate how it can be done using plain vanilla VBA, no need for PowerShell at all.
 

The Code

The Main Function

'---------------------------------------------------------------------------------------
' Procedure : Crypto_GetStringHash
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Returns the specified Hash for the supplied string.
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> none required
' Dependencies: Requires ReadStringAsBinary()
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sInput            : String to get the Hash of
' sHashAlgorithm    : Algorithm to use for the Hashing: MACTripleDES, MD5, RIPEMD160
'                     SHA1, SHA256, SHA384 or SHA512
'
' Usage:
' ~~~~~~
' ? Crypto_GetStringHash("String to get the Hash of", "MD5")
'   Returns -> 69563FFABD2E9D63BF83567F1B664C6
' ? Crypto_GetStringHash("String to get the Hash of", "SHA256")
'   Returns -> 823C17899E52A815FD90EEDDAB5C67B88C1E868E81B88F5ECEFA1D3B17D753
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2023-01-03              Initial Public Release
' 2         2025-08-22              Fix issue reported by Michael
'---------------------------------------------------------------------------------------
Function Crypto_GetStringHash(sInput As String, sHashAlgorithm As String) As String
    On Error GoTo Error_Handler
    Dim oSSCrypto             As Object
    Dim aFileBytes()          As Byte
    Dim hashBytes()           As Byte
    Dim sOutput               As String
    Dim lCounter              As Long

    Select Case sHashAlgorithm
        Case "MACTripleDES"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.MACTripleDES")    '
        Case "MD5"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")    '128 bits
        Case "RIPEMD160"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.RIPEMD160Managed")    '160 bits
        Case "SHA1"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.SHA1Managed")    '160 bits
        Case "SHA256"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.SHA256Managed")    '256 bits
        Case "SHA384"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.SHA384Managed")    '384 bits
        Case "SHA512"
            Set oSSCrypto = CreateObject("System.Security.Cryptography.SHA512Managed")    '512 bits
        Case Else
            'MsgBox ""
            GoTo Error_Handler_Exit
    End Select

    ' Convert input string to bytes
    aFileBytes = StrConv(sInput, vbFromUnicode)
    
    ' Compute the hash
    hashBytes = oSSCrypto.ComputeHash_2(aFileBytes)
    
    ' Convert hash bytes to hex string
    For lCounter = LBound(hashBytes) To UBound(hashBytes)
        sOutput = sOutput & LCase(Right("0" & Hex(hashBytes(lCounter)), 2))
    Next
    Crypto_GetStringHash = sOutput

Error_Handler_Exit:
    On Error Resume Next
    Set oSSCrypto = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: Crypto_GetStringHash" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

The Helper Function

The above relies on one helper function:

'---------------------------------------------------------------------------------------
' Procedure : ReadStringAsBinary
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Converts the supplied string to a binary array
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft ActiveX Data Objects X.X Library
' Based off of ReadFileAsBinary()
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sInput     : String to be converted
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2023-01-03              Initial Public Release
'---------------------------------------------------------------------------------------
Public Function ReadStringAsBinary(ByVal sInput As String) As Variant
On Error GoTo Error_Handler
    '#Const EarlyBind = 1    'Use Early Binding
    #Const EarlyBind = 0    'Use Late Binding
    #If EarlyBind Then
        Dim oADOStream As ADODB.Stream
    #Else
        Dim oADOStream As Object
        Const adTypeBinary = 1
    #End If
    Dim aStringBytes() As Byte

    #If EarlyBind Then
        Set oADOStream = New ADODB.Stream
    #Else
        Set oADOStream = CreateObject("ADODB.Stream")
    #End If
    With oADOStream
        .Charset = "utf-8"
        .Open
        .WriteText sInput
        .Flush
        .Position = 0
        .Type = adTypeBinary
        .Position = 3    'no bom
        aStringBytes() = .Read
    End With
    ReadStringAsBinary = aStringBytes()
 
Error_Handler_Exit:
    On Error Resume Next
    If Not oADOStream Is Nothing Then
        oADOStream.Close
        Set oADOStream = Nothing
    End If
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Source: ReadStringAsBinary" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

 

Usage Example

The main function is very straightforward to use!

? Crypto_GetStringHash("Microsoft Access", "SHA512")

which will return/output a value of

C4208CAAFB46AFA43F246676C8331CAD5B955CF7C2CFE4B4D3E404C75F242E16FE59A41C58984587C6FEAA93C9ED0824C4FD4D6FA2B972BB769A27CD094

Or

? Crypto_GetStringHash("Any String You'd Like to Hash", "MD5")

which will return/output a value of

23954A0132E39C143EA654982F3CE0

 

Self-Healing Object Variables (SHOVs)

Just a quick note to mention that if this is the type of code you will need to run frequently within a solution, then this would be a great place to implement SHOVs to optimize the process and squeeze out every millisecond you can out of your code!

If this is of interest to you, then I’d urge you to review:

 

Other Resources on the Subject

One response on “VBA – Get a String’s Hash

  1. Pac-Man

    This method does require .Net 3.5 which does come pre-intalled with since most of the operating systems.