package controlplane import ( "fmt" "runtime" "unsafe" "golang.org/x/sys/windows" ) // protectSecret binds encrypted data to the current Windows user through DPAPI. // The database stores only this encrypted blob, never a plaintext Provider key. func protectSecret(value string) ([]byte, error) { input := []byte(value) if len(input) == 0 { return nil, fmt.Errorf("API Key 不能为空") } inputBlob := windows.DataBlob{Size: uint32(len(input)), Data: &input[0]} var outputBlob windows.DataBlob if err := windows.CryptProtectData( &inputBlob, nil, nil, 0, nil, windows.CRYPTPROTECT_UI_FORBIDDEN, &outputBlob, ); err != nil { return nil, fmt.Errorf("无法使用 Windows 数据保护保存 API Key: %w", err) } defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(outputBlob.Data)))) protected := unsafe.Slice(outputBlob.Data, int(outputBlob.Size)) result := append([]byte(nil), protected...) runtime.KeepAlive(input) return result, nil } func unprotectSecret(protected []byte) (string, error) { if len(protected) == 0 { return "", fmt.Errorf("未找到 API Key") } inputBlob := windows.DataBlob{Size: uint32(len(protected)), Data: &protected[0]} var outputBlob windows.DataBlob if err := windows.CryptUnprotectData( &inputBlob, nil, nil, 0, nil, windows.CRYPTPROTECT_UI_FORBIDDEN, &outputBlob, ); err != nil { return "", fmt.Errorf("无法读取受保护的 API Key: %w", err) } defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(outputBlob.Data)))) plain := unsafe.Slice(outputBlob.Data, int(outputBlob.Size)) result := string(plain) runtime.KeepAlive(protected) return result, nil }