VBMAN.HashMAC - HMAC Message Authentication Code Object
Overview
VBMAN.HashMAC provides HMAC (Hash-based Message Authentication Code) calculation functionality, supporting HMAC-SHA1 and HMAC-SHA256 algorithms. HMAC uses a secret key to hash data, which can be used for data integrity verification and authentication.
Core Features
- Standard Algorithms: Supports HMAC-SHA1 and HMAC-SHA256 (RFC 2104 standard)
- Flexible Key: Supports key input in string, Hex, and Base64 formats
- UTF8 Support: Perfect support for UTF8 encoded Chinese strings
- Chain Calls: Fluent API design
- Multiple Outputs: Supports Hex, Base64, byte array, and other output formats
Enumerations
HMACAlgorithm
HMAC algorithm enumeration
Public Enum HMACAlgorithm
HMAC_ALG_SHA1 = 32772 ' HMAC-SHA1 algorithm
HMAC_ALG_SHA256 = 32780 ' HMAC-SHA256 algorithm (default)
End EnumHMACStringEncoding
String encoding enumeration
Public Enum HMACStringEncoding
HMAC_ENCODING_ANSI = 0 ' ANSI encoding
HMAC_ENCODING_UTF8 = 1 ' UTF8 encoding (default)
End EnumSecretKeyType
Secret key input type enumeration
Public Enum SecretKeyType
SECRET_KEY_STRING = 0 ' Plain string key
SECRET_KEY_HEX = 1 ' Hex format key
SECRET_KEY_BASE64 = 2 ' Base64 format key
End EnumTraditional Call Methods
SetKey / SetKeyBytes
Set HMAC secret key
' Set key from string
Public Sub SetKey(ByVal KeyString As String, _
Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8)
' Set key from byte array
Public Sub SetKeyBytes(ByRef KeyBytes() As Byte)Example:
' Use string key
VBMAN.HashMAC.SetKey "my_secret_key"
' Use UTF8 encoded key
VBMAN.HashMAC.SetKey "密钥", HMAC_ENCODING_UTF8
' Use byte array key
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")
VBMAN.HashMAC.SetKeyBytes keyBytesCompute
Calculate HMAC of string data (returns hexadecimal string)
Public Function Compute(ByVal Data As String, _
ByVal KeyString As String, _
Optional ByVal Algorithm As HMACAlgorithm, _
Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8) As StringParameters:
Data- The data to signKeyString- The key stringAlgorithm- Optional parameter, HMAC algorithm, defaults to class property value (SHA256)Encoding- Optional parameter, string encoding, defaults to UTF8
Returns: Hexadecimal formatted HMAC string
Example:
' Calculate using HMAC-SHA256
Dim hmac As String
hmac = VBMAN.HashMAC.Compute("Hello World", "my_secret_key", HMAC_ALG_SHA256)
Debug.Print hmac
' Chinese data HMAC calculation
hmac = VBMAN.HashMAC.Compute("邓伟", "密钥", HMAC_ALG_SHA256, HMAC_ENCODING_UTF8)
Debug.Print hmacComputeBytesToHex
Calculate HMAC of byte array (returns hexadecimal string)
Public Function ComputeBytesToHex(ByRef Data() As Byte, _
ByRef Key() As Byte, _
Optional ByVal Algorithm As HMACAlgorithm) As StringExample:
Dim dataBytes() As Byte
dataBytes = VBMAN.ToolsUtf8.Encode("Hello")
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")
Dim hmac As String
hmac = VBMAN.HashMAC.ComputeBytesToHex(dataBytes, keyBytes, HMAC_ALG_SHA256)
Debug.Print hmacComputeBytes
Calculate HMAC of byte array (returns byte array)
Public Function ComputeBytes(ByRef Data() As Byte, _
ByRef Key() As Byte, _
Optional ByVal Algorithm As HMACAlgorithm) As Byte()Example:
Dim dataBytes() As Byte
dataBytes = VBMAN.ToolsUtf8.Encode("Hello")
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")
Dim hmacBytes() As Byte
hmacBytes = VBMAN.HashMAC.ComputeBytes(dataBytes, keyBytes, HMAC_ALG_SHA256)Chain Call Methods (Recommended)
Mode
Set HMAC algorithm (chain call)
Public Function Mode(ByVal Algorithm As HMACAlgorithm) As cCryptoHMACExample:
' Set algorithm to HMAC-SHA256
VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("data").ReturnHex()Secret
Set secret key (chain call)
Public Function Secret(ByVal KeyString As String, _
Optional ByVal KeyType As SecretKeyType = SECRET_KEY_STRING, _
Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8) As cCryptoHMACParameters:
KeyString- The key stringKeyType- Key input type (STRING/HEX/BASE64), default STRINGEncoding- String encoding, default UTF8
Example:
' Plain string key
VBMAN.HashMAC.Secret("my_secret_key").DataString("Hello").ReturnHex()
' Hex format key
VBMAN.HashMAC.Secret("6B6579", SECRET_KEY_HEX).DataString("Hello").ReturnHex()
' Base64 format key
VBMAN.HashMAC.Secret("a2V5", SECRET_KEY_BASE64).DataString("Hello").ReturnHex()SecretBytes
Set key from byte array (chain call)
Public Function SecretBytes(ByRef KeyBytes() As Byte) As cCryptoHMACExample:
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")
VBMAN.HashMAC.SecretBytes(keyBytes).DataString("Hello").ReturnHex()DataString
Input string data (chain call)
Public Function DataString(ByVal Text As String, _
Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8) As cCryptoHMACExample:
' Input UTF8 string
VBMAN.HashMAC.Secret("key").DataString("你好世界", HMAC_ENCODING_UTF8).ReturnHex()
' Input ANSI string
VBMAN.HashMAC.Secret("key").DataString("Hello", HMAC_ENCODING_ANSI).ReturnHex()DataBytes
Input byte array data (chain call)
Public Function DataBytes(ByRef Data() As Byte) As cCryptoHMACExample:
Dim dataBytes() As Byte
dataBytes = VBMAN.ToolsUtf8.Encode("Hello")
VBMAN.HashMAC.Secret("key").DataBytes(dataBytes).ReturnHex()Result Return Methods
ReturnHex
Return hexadecimal formatted HMAC (chain call)
Public Function ReturnHex(Optional ByVal UpperCase As Boolean = False) As StringParameters:
UpperCase- Optional parameter, whether to use uppercase letters, default False (lowercase)
Example:
' Return lowercase HMAC
Dim hmac As String
hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("邓伟").ReturnHex()
Debug.Print hmac
' Return uppercase HMAC
Dim hmacUpper As String
hmacUpper = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("邓伟").ReturnHex(True)
Debug.Print hmacUpperReturnBase64
Return Base64 formatted HMAC (chain call)
Public Function ReturnBase64() As StringExample:
Dim base64Hmac As String
base64Hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("Hello").ReturnBase64()
Debug.Print base64HmacReturnBytes
Return byte array formatted HMAC (chain call)
Public Function ReturnBytes() As Byte()Example:
Dim hmacBytes() As Byte
hmacBytes = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("Hello").ReturnBytes()
' Iterate through byte array
Dim i As Integer
For i = LBound(hmacBytes) To UBound(hmacBytes)
Debug.Print Hex(hmacBytes(i));
NextComprehensive Examples
Example 1: Basic HMAC Calculation (UTF8 Chinese Support)
Private Sub BasicHMACExample()
Dim key As String
Dim data As String
Dim hmac As String
' Chinese key and data
key = "我的密钥"
data = "邓伟"
' HMAC-SHA256 calculation (default UTF8 encoding)
hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(data).ReturnHex()
Debug.Print "HMAC-SHA256: " & hmac
' HMAC-SHA1 calculation
hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA1).Secret(key).DataString(data).ReturnHex()
Debug.Print "HMAC-SHA1: " & hmac
' Using traditional method
hmac = VBMAN.HashMAC.Compute(data, key, HMAC_ALG_SHA256)
Debug.Print "Traditional method: " & hmac
End SubExample 2: API Request Signature
Private Function GenerateAPISignature(apiKey As String, apiSecret As String, _
params As String, timestamp As String) As String
' Build data to sign
Dim dataToSign As String
dataToSign = apiKey & "|" & params & "|" & timestamp
' Calculate signature using HMAC-SHA256
Dim signature As String
signature = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(apiSecret).DataString(dataToSign).ReturnHex(True)
GenerateAPISignature = signature
End Function
Private Sub TestAPIRequest()
Dim apiKey As String
Dim apiSecret As String
Dim params As String
Dim timestamp As String
Dim signature As String
apiKey = "AKIAIOSFODNN7EXAMPLE"
apiSecret = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
params = "action=getUser&id=12345"
timestamp = CStr(Now())
signature = GenerateAPISignature(apiKey, apiSecret, params, timestamp)
Debug.Print "API Key: " & apiKey
Debug.Print "Timestamp: " & timestamp
Debug.Print "Signature: " & signature
End SubExample 3: Webhook Signature Verification
Private Function VerifyWebhookSignature(payload As String, signature As String, secret As String) As Boolean
' Calculate expected signature
Dim expectedSignature As String
expectedSignature = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(secret).DataString(payload).ReturnHex()
' Compare signatures (case-insensitive)
VerifyWebhookSignature = (LCase(expectedSignature) = LCase(signature))
End Function
Private Sub TestWebhookVerification()
Dim secret As String
Dim payload As String
Dim receivedSignature As String
Dim isValid As Boolean
secret = "webhook_secret_key"
payload = "{event:user.created,user_id:12345}"
receivedSignature = "a1b2c3d4..." ' Received signature
isValid = VerifyWebhookSignature(payload, receivedSignature, secret)
If isValid Then
Debug.Print "Webhook signature verification passed"
Else
Debug.Print "Webhook signature verification failed"
End If
End SubExample 4: Message Integrity Verification
Private Function CreateMessageWithMAC(message As String, key As String) As String
' Calculate HMAC
Dim mac As String
mac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(message).ReturnHex()
' Append MAC to message
CreateMessageWithMAC = message & "|" & mac
End Function
Private Function VerifyAndExtractMessage(messageWithMAC As String, key As String) As String
On Error GoTo ErrorHandler
' Separate message and MAC
Dim parts() As String
parts = Split(messageWithMAC, "|")
If UBound(parts) <> 1 Then
VerifyAndExtractMessage = ""
Exit Function
End If
Dim message As String
Dim receivedMAC As String
message = parts(0)
receivedMAC = parts(1)
' Recalculate MAC
Dim calculatedMAC As String
calculatedMAC = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(message).ReturnHex()
' Verify MAC
If LCase(calculatedMAC) = LCase(receivedMAC) Then
VerifyAndExtractMessage = message
Else
VerifyAndExtractMessage = "" ' Verification failed
End If
Exit Function
ErrorHandler:
VerifyAndExtractMessage = ""
End Function
Private Sub TestMessageIntegrity()
Dim key As String
Dim originalMessage As String
Dim messageWithMAC As String
Dim extractedMessage As String
key = "shared_secret_key"
originalMessage = "Important data: Transfer amount 1000 yuan"
' Sender creates message with MAC
messageWithMAC = CreateMessageWithMAC(originalMessage, key)
Debug.Print "Message with MAC: " & messageWithMAC
' Receiver verifies and extracts message
extractedMessage = VerifyAndExtractMessage(messageWithMAC, key)
If extractedMessage <> "" Then
Debug.Print "Message verification passed: " & extractedMessage
Else
Debug.Print "Message verification failed"
End If
End SubBest Practices
- Key Security: HMAC keys should be stored securely, do not hardcode them in code
- Algorithm Selection: HMAC-SHA256 is recommended for higher security
- UTF8 Encoding: Use UTF8 encoding by default when processing Chinese strings
- Key Length: Key length should be at least 32 bytes (256 bits)
- Signature Comparison: Use constant-time comparison when comparing HMAC values to prevent timing attacks
- Chain Calls: Recommended to use chain call method for clearer code
HMAC vs Regular Hash
| Feature | HMAC | Regular Hash (MD5/SHA) |
|---|---|---|
| Key | Requires key | No key required |
| Purpose | Authentication, integrity verification | Data verification, fingerprinting |
| Security | High (depends on key) | Medium (tamper-proof only) |
| Use Cases | API signatures, Tokens | File verification, Cache keys |
Common Application Scenarios
- API Request Signing: Verify request source and integrity
- Webhook Verification: Confirm authenticity of callback notifications
- Message Authentication: Ensure messages have not been tampered with
- Token Generation: Create signed temporary tokens
- File Transfer: Verify integrity of transferred files