高性能跨平台机器码生成库,支持多种操作系统和容器环境,提供安全的机器标识和授权管理功能。

go get github.com/darkit/machineid
命令行工具安装:
go install github.com/darkit/machineid/cmd/machineid@latest
package main
import (
"fmt"
"log"
"github.com/darkit/machineid"
)
func main() {
// 获取原始机器码
id, err := machineid.ID()
if err != nil {
log.Fatal(err)
}
fmt.Printf("机器码: %s\n", id)
// 获取应用专属的受保护机器码(推荐)
protectedID, err := machineid.ProtectedID("your.app.id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("受保护机器码: %s\n", protectedID)
// 获取唯一性增强机器码(默认容器唯一)
uniqueID, err := machineid.UniqueID("your.app.id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("唯一性增强机器码: %s\n", uniqueID)
}
package main
import (
"fmt"
"log"
"github.com/darkit/machineid"
)
func main() {
// 获取系统信息摘要
info, err := machineid.GetInfo("your.app.id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("机器码: %s\n", info.MachineID)
fmt.Printf("受保护机器码: %s\n", info.ProtectedID)
fmt.Printf("MAC地址: %s\n", info.MACAddress)
fmt.Printf("是否为容器: %t\n", info.IsContainer)
if info.ContainerID != "" {
fmt.Printf("容器ID: %s\n", info.ContainerID)
}
}
// ProtectedID 现在自动使用最佳可用的硬件绑定方式
// 优先级:硬件指纹 > MAC地址 > 纯机器码
protectedID, err := machineid.ProtectedID("your.app.id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("智能保护机器码: %s\n", protectedID)
// 宿主机唯一(容器内可切换)
hostUnique, err := machineid.UniqueIDResult("your.app.id", &machineid.UniqueIDOptions{
Mode: machineid.UniqueIDModeHost,
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("宿主机唯一机器码: %s\n", hostUnique.Hash)
// 直接获取MAC地址(可选)
macAddr, err := machineid.GetMACAddress()
if err != nil {
log.Fatal(err)
}
fmt.Printf("主网卡MAC: %s\n", macAddr)
如果需要扩展绑定来源(例如磁盘序列号、云厂商元数据),可以注册自定义提供者:
machineid.RegisterBindingProvider("disk", func(appID, machineID string) (string, bool, error) {
serial, err := readDiskSerial()
if err != nil || serial == "" {
return "", false, err
}
return serial, true, nil
})
当内置硬件指纹和 MAC 绑定不可用时,ProtectedID 会尝试自定义提供者,并在 BindingResult 中返回 Mode="custom"、Provider="disk" 等信息。
// 检查是否运行在容器中
if machineid.IsContainer() {
fmt.Println("运行在容器环境中")
} else {
fmt.Println("运行在物理机或虚拟机中")
}
容器指纹会在检测到 Kubernetes 环境变量时自动纳入 Pod/Node 相关提示(无需访问集群 API)。
可用变量包括:POD_UID、POD_NAME、POD_NAMESPACE、NODE_NAME 等。
| 函数 | 描述 | 返回值 |
|---|---|---|
ID() | 获取原始机器码 | (string, error) |
ProtectedID(appID) | 获取智能硬件绑定的保护机器码(推荐) | (string, error) |
GetInfo(appID) | 获取完整系统信息(推荐) | (*Info, error) |
GetMACAddress() | 获取主网卡MAC地址 | (string, error) |
IsContainer() | 检查是否在容器环境 | bool |
ClearCache() | 清除所有缓存 | void |
type Info struct {
MachineID string `json:"machine_id"` // 原始机器码
ProtectedID string `json:"protected_id"` // 智能保护机器码
MACAddress string `json:"mac_address,omitempty"` // MAC地址
IsContainer bool `json:"is_container"` // 是否容器环境
ContainerID string `json:"container_id,omitempty"` // 容器ID
}
本库还提供了完整的 PKI 证书管理功能,用于软件授权和客户信息管理。
📚 详细文档:完整的证书管理功能请参阅 cert包文档
package main
import (
"time"
"github.com/darkit/machineid"
"github.com/darkit/machineid/cert"
)
func main() {
// 创建授权管理器(默认开发友好,无安全检查)
auth, err := cert.NewAuthorizer().
WithRuntimeVersion("2.5.0"). // 设置当前运行的软件版本
Build()
if err != nil {
panic(err)
}
// 获取机器码(使用标准ProtectedIDResult 以保留绑定来源)
bindingResult, _ := machineid.ProtectedIDResult("your.app.id")
machineID := bindingResult.Hash
// 构建证书请求
request, err := cert.NewClientRequest().
WithMachineID(machineID).
WithBindingResult(bindingResult).
WithExpiry(time.Now().AddDate(1, 0, 0)).
WithCompany("示例科技公司", "研发部").
WithContact("张经理", "13800138000", "zhang@example.com").
WithMinClientVersion("2.0.0").
WithValidityDays(365).
Build()
// 签发证书
certificate, err := auth.IssueClientCert(request)
if err != nil {
panic(err)
}
// 验证证书
err = auth.ValidateCert(certificate.CertPEM, machineID)
if err != nil {
panic(err)
}
// 提取客户信息
clientInfo, err := auth.ExtractClientInfo(certificate.CertPEM)
if err == nil {
fmt.Printf("授权给: %s (%s)\n", clientInfo.CompanyName, clientInfo.ContactPerson)
fmt.Printf("联系方式: %s\n", clientInfo.ContactEmail)
fmt.Printf("绑定模式: %s\n", clientInfo.BindingMode)
fmt.Printf("绑定提供者: %s\n", clientInfo.BindingProvider)
fmt.Printf("到期时间: %s\n", clientInfo.ExpiryDate.Format("2006-01-02"))
}
// 启动智能监控(可选)
watchCallback := func(event cert.WatchEvent, info *cert.ClientInfo, err error) {
switch event {
case cert.WatchEventExpiring:
fmt.Printf("警告: 证书即将到期 - %s\n", info.CompanyName)
case cert.WatchEventExpired:
fmt.Printf("紧急: 证书已过期 - %s\n", info.CompanyName)
}
}
// 启动监控(1小时检查间隔,7天预警期)
watcher, _ := auth.Watch(certificate.CertPEM, machineID, watchCallback)
defer watcher.Stop()
}
💡 版本提示:
WithRuntimeVersion表示当前正在运行的软件实际版本,用于校验证书要求;WithMinClientVersion表示签发证书时要求客户端至少达到的版本,两者互不冲突。
// 开发环境(无安全检查,推荐)
devAuth, _ := cert.ForDevelopment().Build()
// 生产环境(基础安全检查)
prodAuth, _ := cert.ForProduction().Build()
// 高安全环境(完整反调试保护)
secureAuth, _ := cert.NewAuthorizer().WithSecureDefaults().Build()
// 关键系统(最高安全级别)
criticalAuth, _ := cert.NewAuthorizer().WithCriticalSecurity().Build()
// 从任何证书中提取完整的客户信息
clientInfo, err := auth.ExtractClientInfo(certPEM)
if err != nil {
// 处理错误
}
fmt.Printf("公司: %s\n", clientInfo.CompanyName)
fmt.Printf("联系人: %s (%s)\n", clientInfo.ContactPerson, clientInfo.ContactEmail)
fmt.Printf("到期时间: %s\n", clientInfo.ExpiryDate.Format("2006-01-02"))
// 定义监控回调处理不同事件
watchCallback := func(event cert.WatchEvent, clientInfo *cert.ClientInfo, err error) {
switch event {
case cert.WatchEventExpiring:
// 证书即将到期(默认7天预警)
sendRenewalNotification(clientInfo)
case cert.WatchEventExpired:
// 证书已过期
disableService(clientInfo)
case cert.WatchEventRevoked:
// 证书被吊销
handleSecurityIncident(clientInfo)
}
}
// 启动监控(支持自定义间隔)
watcher, err := auth.Watch(certPEM, machineID, watchCallback,
time.Hour, // 检查间隔(可选,默认1小时)
3*24*time.Hour) // 预警期(可选,默认7天)
// 监控管理器(管理多个证书)
manager := cert.NewWatcherManager()
manager.AddWatcher("license1", watcher1)
manager.AddWatcher("license2", watcher2)
| 操作系统 | 主要来源 | 备用来源 |
|---|---|---|
| Windows | 注册表 MachineGuid | - |
| Linux | /var/lib/dbus/machine-id | /etc/machine-id, $HOME/.config/machine-id |
| macOS | IOPlatformUUID | - |
| FreeBSD | /etc/hostid | smbios.system.uuid |
| AIX | uname -u | - |
Linux 容器检测:
/proc/self/cgroup 和 /proc/self/mountinfoCONTAINER_ID、DOCKER_CONTAINER_ID其他系统:
/.dockerenv 文件原始机器码保护
ProtectedID() 而非 ID()加密算法
智能硬件绑定
ProtectedID() 自动选择最佳可用的硬件绑定方式# 获取原始机器码
machineid
# 获取应用专属机器码
machineid --appid MyApp
# 输出示例
# 原始: 8245d07ef271816592fbd6172e521a945bdc4e3dca2fd91ef57cddf5a298b73f
# 应用专属: DCEF03E8DB3B602695BAFE227E6CC73180807D3A0FDAB459EC0A8FA2DCA1E99E
# 运行所有测试
go test -v
# 运行基准测试
go test -bench=.
# 测试覆盖率
go test -cover
本版本与原版 API 完全兼容,主要改进包括:
// 原版用法(仍然支持)
id, _ := machineid.ID()
protectedID, _ := machineid.ProtectedID("app")
// 新版建议用法
info, _ := machineid.GetInfo("app")
// 使用 info.MachineID 和 info.ProtectedID
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)$HOME/.config/machine-id 在某些环境下可能不可用MIT License - 详见 LICENSE 文件
⭐ 如果这个项目对你有帮助,请给我们一个 Star!