Skip to content

VBMAN.HashMAC - HMAC 消息认证码对象

概述

VBMAN.HashMAC 提供了 HMAC(Hash-based Message Authentication Code)消息认证码计算功能,支持 HMAC-SHA1 和 HMAC-SHA256 算法。HMAC 使用密钥对数据进行哈希计算,可用于验证数据完整性和身份认证。

核心特性

  • 标准算法: 支持 HMAC-SHA1 和 HMAC-SHA256(RFC 2104 标准)
  • 密钥灵活: 支持字符串、Hex、Base64 格式的密钥输入
  • UTF8 支持: 完美支持 UTF8 编码的中文字符串
  • 链式调用: 流畅的 API 设计
  • 多种输出: 支持 Hex、Base64、字节数组等多种输出格式

枚举

HMACAlgorithm

HMAC 算法枚举

vb
Public Enum HMACAlgorithm
    HMAC_ALG_SHA1 = 32772       ' HMAC-SHA1 算法
    HMAC_ALG_SHA256 = 32780     ' HMAC-SHA256 算法(默认)
End Enum

HMACStringEncoding

字符串编码枚举

vb
Public Enum HMACStringEncoding
    HMAC_ENCODING_ANSI = 0      ' ANSI 编码
    HMAC_ENCODING_UTF8 = 1      ' UTF8 编码(默认)
End Enum

SecretKeyType

密钥输入类型枚举

vb
Public Enum SecretKeyType
    SECRET_KEY_STRING = 0       ' 普通字符串密钥
    SECRET_KEY_HEX = 1          ' Hex 格式密钥
    SECRET_KEY_BASE64 = 2       ' Base64 格式密钥
End Enum

传统调用方法

SetKey / SetKeyBytes

设置 HMAC 密钥

vb
' 从字符串设置密钥
Public Sub SetKey(ByVal KeyString As String, _
                  Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8)

' 从字节数组设置密钥
Public Sub SetKeyBytes(ByRef KeyBytes() As Byte)

示例:

vb
' 使用字符串密钥
VBMAN.HashMAC.SetKey "my_secret_key"

' 使用 UTF8 编码的密钥
VBMAN.HashMAC.SetKey "密钥", HMAC_ENCODING_UTF8

' 使用字节数组密钥
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")
VBMAN.HashMAC.SetKeyBytes keyBytes

Compute

计算字符串数据的 HMAC(返回十六进制字符串)

vb
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 String

参数:

  • Data - 要签名的数据
  • KeyString - 密钥字符串
  • Algorithm - 可选参数,HMAC 算法,默认使用类属性值 (SHA256)
  • Encoding - 可选参数,字符串编码,默认 UTF8

返回: 十六进制格式的 HMAC 字符串

示例:

vb
' 使用 HMAC-SHA256 计算
Dim hmac As String
hmac = VBMAN.HashMAC.Compute("Hello World", "my_secret_key", HMAC_ALG_SHA256)
Debug.Print hmac

' 中文数据 HMAC 计算
hmac = VBMAN.HashMAC.Compute("邓伟", "密钥", HMAC_ALG_SHA256, HMAC_ENCODING_UTF8)
Debug.Print hmac

ComputeBytesToHex

计算字节数组的 HMAC(返回十六进制字符串)

vb
Public Function ComputeBytesToHex(ByRef Data() As Byte, _
                                  ByRef Key() As Byte, _
                                  Optional ByVal Algorithm As HMACAlgorithm) As String

示例:

vb
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 hmac

ComputeBytes

计算字节数组的 HMAC(返回字节数组)

vb
Public Function ComputeBytes(ByRef Data() As Byte, _
                             ByRef Key() As Byte, _
                             Optional ByVal Algorithm As HMACAlgorithm) As Byte()

示例:

vb
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)

链式调用方法(推荐)

Mode

设置 HMAC 算法(链式调用)

vb
Public Function Mode(ByVal Algorithm As HMACAlgorithm) As cCryptoHMAC

示例:

vb
' 设置算法为 HMAC-SHA256
VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("data").ReturnHex()

Secret

设置密钥(链式调用)

vb
Public Function Secret(ByVal KeyString As String, _
                    Optional ByVal KeyType As SecretKeyType = SECRET_KEY_STRING, _
                    Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8) As cCryptoHMAC

参数:

  • KeyString - 密钥字符串
  • KeyType - 密钥输入类型(STRING/HEX/BASE64),默认 STRING
  • Encoding - 字符串编码,默认 UTF8

示例:

vb
' 普通字符串密钥
VBMAN.HashMAC.Secret("my_secret_key").DataString("Hello").ReturnHex()

' Hex 格式密钥
VBMAN.HashMAC.Secret("6B6579", SECRET_KEY_HEX).DataString("Hello").ReturnHex()

' Base64 格式密钥
VBMAN.HashMAC.Secret("a2V5", SECRET_KEY_BASE64).DataString("Hello").ReturnHex()

SecretBytes

从字节数组设置密钥(链式调用)

vb
Public Function SecretBytes(ByRef KeyBytes() As Byte) As cCryptoHMAC

示例:

vb
Dim keyBytes() As Byte
keyBytes = VBMAN.ToolsUtf8.Encode("secret")

VBMAN.HashMAC.SecretBytes(keyBytes).DataString("Hello").ReturnHex()

DataString

输入字符串数据(链式调用)

vb
Public Function DataString(ByVal Text As String, _
                           Optional ByVal Encoding As HMACStringEncoding = HMAC_ENCODING_UTF8) As cCryptoHMAC

示例:

vb
' 输入 UTF8 字符串
VBMAN.HashMAC.Secret("key").DataString("你好世界", HMAC_ENCODING_UTF8).ReturnHex()

' 输入 ANSI 字符串
VBMAN.HashMAC.Secret("key").DataString("Hello", HMAC_ENCODING_ANSI).ReturnHex()

DataBytes

输入字节数组数据(链式调用)

vb
Public Function DataBytes(ByRef Data() As Byte) As cCryptoHMAC

示例:

vb
Dim dataBytes() As Byte
dataBytes = VBMAN.ToolsUtf8.Encode("Hello")

VBMAN.HashMAC.Secret("key").DataBytes(dataBytes).ReturnHex()

结果返回方法

ReturnHex

返回十六进制格式的 HMAC(链式调用)

vb
Public Function ReturnHex(Optional ByVal UpperCase As Boolean = False) As String

参数:

  • UpperCase - 可选参数,是否使用大写字母,默认 False(小写)

示例:

vb
' 返回小写 HMAC
Dim hmac As String
hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("邓伟").ReturnHex()
Debug.Print hmac

' 返回大写 HMAC
Dim hmacUpper As String
hmacUpper = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("邓伟").ReturnHex(True)
Debug.Print hmacUpper

ReturnBase64

返回 Base64 格式的 HMAC(链式调用)

vb
Public Function ReturnBase64() As String

示例:

vb
Dim base64Hmac As String
base64Hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("Hello").ReturnBase64()
Debug.Print base64Hmac

ReturnBytes

返回字节数组格式的 HMAC(链式调用)

vb
Public Function ReturnBytes() As Byte()

示例:

vb
Dim hmacBytes() As Byte
hmacBytes = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret("key").DataString("Hello").ReturnBytes()

' 遍历字节数组
Dim i As Integer
For i = LBound(hmacBytes) To UBound(hmacBytes)
    Debug.Print Hex(hmacBytes(i));
Next

综合示例

示例1: 基础 HMAC 计算(UTF8 中文支持)

vb
Private Sub BasicHMACExample()
    Dim key As String
    Dim data As String
    Dim hmac As String
    
    ' 中文密钥和数据
    key = "我的密钥"
    data = "邓伟"
    
    ' HMAC-SHA256 计算(默认 UTF8 编码)
    hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(data).ReturnHex()
    Debug.Print "HMAC-SHA256: " & hmac
    
    ' HMAC-SHA1 计算
    hmac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA1).Secret(key).DataString(data).ReturnHex()
    Debug.Print "HMAC-SHA1: " & hmac
    
    ' 使用传统方法
    hmac = VBMAN.HashMAC.Compute(data, key, HMAC_ALG_SHA256)
    Debug.Print "传统方法: " & hmac
End Sub

示例2: API 请求签名

vb
Private Function GenerateAPISignature(apiKey As String, apiSecret As String, _
                                     params As String, timestamp As String) As String
    ' 构建待签名数据
    Dim dataToSign As String
    dataToSign = apiKey & "|" & params & "|" & timestamp
    
    ' 使用 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 Sub

示例3: Webhook 签名验证

vb
Private Function VerifyWebhookSignature(payload As String, signature As String, secret As String) As Boolean
    ' 计算期望的签名
    Dim expectedSignature As String
    expectedSignature = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(secret).DataString(payload).ReturnHex()
    
    ' 比较签名(不区分大小写)
    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..."  ' 接收到的签名
    
    isValid = VerifyWebhookSignature(payload, receivedSignature, secret)
    
    If isValid Then
        Debug.Print "Webhook 签名验证通过"
    Else
        Debug.Print "Webhook 签名验证失败"
    End If
End Sub

示例4: 消息完整性校验

vb
Private Function CreateMessageWithMAC(message As String, key As String) As String
    ' 计算 HMAC
    Dim mac As String
    mac = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(message).ReturnHex()
    
    ' 将 MAC 附加到消息中
    CreateMessageWithMAC = message & "|" & mac
End Function

Private Function VerifyAndExtractMessage(messageWithMAC As String, key As String) As String
    On Error GoTo ErrorHandler
    
    ' 分离消息和 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)
    
    ' 重新计算 MAC
    Dim calculatedMAC As String
    calculatedMAC = VBMAN.HashMAC.Mode(HMAC_ALG_SHA256).Secret(key).DataString(message).ReturnHex()
    
    ' 验证 MAC
    If LCase(calculatedMAC) = LCase(receivedMAC) Then
        VerifyAndExtractMessage = message
    Else
        VerifyAndExtractMessage = ""  ' 验证失败
    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 = "重要数据:转账金额1000元"
    
    ' 发送方创建带 MAC 的消息
    messageWithMAC = CreateMessageWithMAC(originalMessage, key)
    Debug.Print "带 MAC 的消息: " & messageWithMAC
    
    ' 接收方验证并提取消息
    extractedMessage = VerifyAndExtractMessage(messageWithMAC, key)
    
    If extractedMessage <> "" Then
        Debug.Print "消息验证通过: " & extractedMessage
    Else
        Debug.Print "消息验证失败"
    End If
End Sub

最佳实践

  1. 密钥安全: HMAC 密钥应安全存储,不要硬编码在代码中
  2. 算法选择: 推荐使用 HMAC-SHA256,安全性更高
  3. UTF8 编码: 处理中文字符串时,默认使用 UTF8 编码
  4. 密钥长度: 密钥长度建议至少 32 字节(256位)
  5. 签名比较: 比较 HMAC 值时使用恒定时间比较,防止时序攻击
  6. 链式调用: 推荐使用链式调用方式,代码更清晰

HMAC vs 普通哈希

特性HMAC普通哈希 (MD5/SHA)
密钥需要密钥不需要密钥
用途身份认证、完整性校验数据校验、指纹
安全性高(依赖密钥)中(仅防篡改)
应用场景API 签名、Token文件校验、缓存键

常见应用场景

  1. API 请求签名: 验证请求来源和完整性
  2. Webhook 验证: 确认回调通知的真实性
  3. 消息认证: 确保消息未被篡改
  4. Token 生成: 创建带签名的临时令牌
  5. 文件传输: 验证传输文件的完整性

VB6及其LOGO版权为微软公司所有