Files
yml2213 040100f290 feat(dcauth): 新增后台手机号与设备认证登录
登录链路改为账号密码 + 短信验证码 + DCAuth 设备签名,并新增后台手机号绑定、
登录日志、设备绑定与重置接口。
2026-10-21 20:46:24 +08:00

74 lines
1.6 KiB
Go

//go:build windows
package main
import (
"fmt"
"syscall"
"unsafe"
)
type dataBlob struct {
cbData uint32
pbData *byte
}
var (
crypt32DLL = syscall.NewLazyDLL("crypt32.dll")
kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
cryptProtectData = crypt32DLL.NewProc("CryptProtectData")
unprotect = crypt32DLL.NewProc("CryptUnprotectData")
localFree = kernel32DLL.NewProc("LocalFree")
)
func protectData(data []byte) ([]byte, error) {
if len(data) == 0 {
return nil, fmt.Errorf("empty data")
}
input := dataBlob{cbData: uint32(len(data)), pbData: &data[0]}
var output dataBlob
result, _, err := cryptProtectData.Call(
uintptr(unsafe.Pointer(&input)),
0,
0,
0,
0,
0,
uintptr(unsafe.Pointer(&output)),
)
if result == 0 {
return nil, fmt.Errorf("CryptProtectData failed: %w", err)
}
defer localFree.Call(uintptr(unsafe.Pointer(output.pbData)))
return cloneBlob(output), nil
}
func unprotectData(data []byte) ([]byte, error) {
if len(data) == 0 {
return nil, fmt.Errorf("empty data")
}
input := dataBlob{cbData: uint32(len(data)), pbData: &data[0]}
var output dataBlob
result, _, err := unprotect.Call(
uintptr(unsafe.Pointer(&input)),
0,
0,
0,
0,
0,
uintptr(unsafe.Pointer(&output)),
)
if result == 0 {
return nil, fmt.Errorf("CryptUnprotectData failed: %w", err)
}
defer localFree.Call(uintptr(unsafe.Pointer(output.pbData)))
return cloneBlob(output), nil
}
func cloneBlob(blob dataBlob) []byte {
if blob.pbData == nil || blob.cbData == 0 {
return nil
}
return append([]byte(nil), unsafe.Slice(blob.pbData, int(blob.cbData))...)
}