ak/sk是一种身份认证方式,常用于系统间接口调用时的身份验证,其中ak为Access Key ID,sk为Secret Access Key。客户端和服务端两者会协商保存一份相同的sk,其中sk必须保密。
2. AK/SK认证过程客户端在调用的服务端接口时候,会带上ak以及signature(使用sk对内容进行加密后得出的签名)进行请求,在服务端接收到这个请求的时候,首先会根据ak去数据库里面去找到对应的sk,然后使用sk对请求内容进行加密得到一个签名,然后对比客户端传过来的签名和服务端计算的出来的签名是否一致,如果一致则代表身份认证通过,反之则不通过。
当发送请求时,我们会带上这几个参数去请求接口,如请求https:///xxx.com/students?platform_type=school&time=1640494526&sign=54acba6857b284a8a481ed5913edd34d994721cc584305ff02c81bb3ced17212
2. 数据库中保存sk一般来说,我们的sk生成是采用随机生成的方式,生成一个长度为64的随机字符串即可。
在数据库中我们可以生成这样的一个表
CREATE TABLE `app_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`access key` varchar(50) NOT NULL,
`secret_key` varchar(64) NOT NULL,
`status` int(11) NOT NULL DEFAULT 1,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) USING BTREE
)
在表中插入对应的一条数据
INSERT INTO app_permission ( `access key`, `secret_key`)
VALUES
( 'school', '7QFxrZ4aDA1mR5J96LwPoiO8HUgnefCvq2SMlz0IEtYsuyjbpNXcGW3TBkKVdhch');
3. 客户端生成签名
package main
import (
"crypto"
"crypto/hmac"
_ "crypto/sha256"
"encoding/hex"
"errors"
"strconv"
"time"
"github.com/beego/beego/v2/core/logs"
)
const (
defaultHash = crypto.SHA256
)
func main() {
//此处省略了从数据库读取sk的步骤
secret := "7QFxrZ4aDA1mR5J96LwPoiO8HUgnefCvq2SMlz0IEtYsuyjbpNXcGW3TBkKVdhch"
now := time.Now().Unix()
timestamp := strconv.FormatInt(now, 10)
//生成签名
sign, err := GenerateSignature(timestamp, secret)
if err != nil {
logs.Warn("generate sign failed: %s", err.Error())
return
}
logs.Debug("time: %s", timestamp)
logs.Debug("sign: %s", sign)
}
//GenerateSignature 传入加密的内容和secret进行签名
func GenerateSignature(content, secret string) (string, error) {
//判断设置的默认签名算法是否可用
if !defaultHash.Available() {
return "", errors.New("the requested hash function is unavailable")
}
//设置加密算法以及secret
hasher := hmac.New(defaultHash.New, []byte(secret))
//写入加密内容
hasher.Write([]byte(content))
//生成签名
return hex.EncodeToString(hasher.Sum(nil)), nil
}
4. 服务端校验签名
package main
import (
"crypto"
"crypto/hmac"
_ "crypto/sha256"
"encoding/hex"
"errors"
"github.com/beego/beego/v2/core/logs"
)
const (
defaultHash = crypto.SHA256
)
func main() {
//此处省略了从数据库读取sk的步骤
secret := "7QFxrZ4aDA1mR5J96LwPoiO8HUgnefCvq2SMlz0IEtYsuyjbpNXcGW3TBkKVdhch"
timestamp := "1640494526"
sign := "54acba6857b284a8a481ed5913edd34d994721cc584305ff02c81bb3ced17212"
//服务端验证签名
if err := VerifySignature(timestamp, sign, secret); err != nil {
logs.Warn("verify signature failed, err: %s", err)
return
}
logs.Debug("verify signature success")
}
//VerifySignature 校验签名
func VerifySignature(content, sign, secret string) error {
//解码
sig, err := hex.DecodeString(sign)
if err != nil {
return err
}
//判断加密算法是否可用
if !defaultHash.Available() {
return errors.New("the requested hash function is unavailable")
}
//设置secret
hasher := hmac.New(defaultHash.New, []byte(secret))
//写入加密内容
hasher.Write([]byte(content))
//判断签名是否一致
if !hmac.Equal(sig, hasher.Sum(nil)) {
return errors.New("signature is invalid")
}
return nil
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)