You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Go实现LDAP Salted MD5密码的验证功能

如何使用Go验证明文密码与加盐MD5(LDAP SMD5)密码是否一致?

LDAP的加盐MD5(SMD5)密码格式为{SMD5}<Base64编码内容>,其中Base64解码后的字节序列包含两部分:前16字节是MD5(明文密码+盐)的哈希值,剩余部分是随机生成的盐(通常为8字节)。验证的核心逻辑是用明文密码拼接盐重新计算MD5哈希,再与存储的哈希值对比。

Go实现代码

package main

import (
	"crypto/md5"
	"encoding/base64"
	"fmt"
	"strings"
	"bytes"
)

// VerifySMD5 验证明文密码与LDAP SMD5格式的哈希是否匹配
func VerifySMD5(plainPassword, smd5Hash string) bool {
	// 校验并移除{SMD5}前缀
	if !strings.HasPrefix(smd5Hash, "{SMD5}") {
		return false
	}
	encoded := strings.TrimPrefix(smd5Hash, "{SMD5}")

	// Base64解码原始内容
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		return false
	}

	// 校验解码后长度(至少包含16字节MD5哈希)
	if len(decoded) < 16 {
		return false
	}

	// 分离存储的哈希值与盐
	storedHash := decoded[:16]
	salt := decoded[16:]

	// 计算明文密码+盐的MD5哈希
	h := md5.New()
	h.Write([]byte(plainPassword))
	h.Write(salt)
	calculatedHash := h.Sum(nil)

	// 对比两个哈希值(bytes.Equal比字符串对比更严谨)
	return bytes.Equal(calculatedHash, storedHash)
}

func main() {
	// 测试示例1
	plainPass := "123456"
	smd5Pass := "{SMD5}991RjK3DQCT+ri/yxQB613Yuxdg="
	fmt.Printf("验证结果1: %t\n", VerifySMD5(plainPass, smd5Pass)) // 输出 true

	// 测试示例2
	smd5Pass2 := "{SMD5}ZmDHoIiZZG/weuCNkLj189sFoPM="
	fmt.Printf("验证结果2: %t\n", VerifySMD5(plainPass, smd5Pass2)) // 输出 true
}

代码说明

  1. 前缀校验:先确认输入的哈希字符串符合SMD5格式,移除前缀后获取核心的Base64编码内容。
  2. 解码处理:对编码内容进行Base64解码,解码失败则直接判定验证不通过。
  3. 内容拆分:按照SMD5的格式规则,从解码后的字节中分离出16字节的哈希值和剩余的盐。
  4. 哈希重算:使用Go标准库的crypto/md5包,计算明文密码拼接盐后的哈希值。
  5. 哈希对比:用bytes.Equal对比计算出的哈希与存储的哈希,确保字节序列完全一致。

内容的提问来源于stack exchange,提问作者CyberWon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:43:12