49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
// Package apikey 生成与管理 API Key:sk-ot- + 48 位 base62 随机串。
|
||
// 库中仅存 SHA-256 哈希与展示前缀(PLANNING §4.3.3)。
|
||
package apikey
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"crypto/sha256"
|
||
"encoding/hex"
|
||
"strings"
|
||
)
|
||
|
||
const (
|
||
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||
keyLen = 48
|
||
prefix = "sk-ot-"
|
||
)
|
||
|
||
// Generate 生成明文 key(仅创建时展示一次)与哈希、前缀。
|
||
func Generate() (plain, hash, keyPrefix string, err error) {
|
||
buf := make([]byte, keyLen)
|
||
if _, err = rand.Read(buf); err != nil {
|
||
return "", "", "", err
|
||
}
|
||
for i := range buf {
|
||
buf[i] = alphabet[int(buf[i])%len(alphabet)]
|
||
}
|
||
plain = prefix + string(buf)
|
||
return plain, Hash(plain), Prefix(plain), nil
|
||
}
|
||
|
||
// Hash 返回 key 的 SHA-256 十六进制。
|
||
func Hash(key string) string {
|
||
sum := sha256.Sum256([]byte(key))
|
||
return hex.EncodeToString(sum[:])
|
||
}
|
||
|
||
// Prefix 展示前缀:sk-ot-aB3c…(前 12 字符)
|
||
func Prefix(key string) string {
|
||
if len(key) <= 12 {
|
||
return key
|
||
}
|
||
return key[:12]
|
||
}
|
||
|
||
// Valid 校验明文格式。
|
||
func Valid(key string) bool {
|
||
return strings.HasPrefix(key, prefix) && len(key) == len(prefix)+keyLen
|
||
}
|