详解 go-zero 的签名机制

admin 2024年9月22日13:52:21评论2 views字数 1748阅读5分49秒阅读模式

go-zero 自带一个 API 签名机制[1] 但语焉不详。本文就来说说其细节。

如何配置

签名当然要用到非对称加密,需要准备好公私钥一对。生成的命令[2]

# 生成私钥,保存为 private.pem 文件
openssl genrsa -traditional -out private.pem 2048
# 生成公钥,保存为 public.pem 文件
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

-traditional原因[3]是咱们需要生成旧格式的私钥[4]x509.ParsePKCS1PrivateKey 使用。

为需要签名的 API 打开开关,参见官方文档不再赘述,下面以打开了签名开关的 API /user/modify 为例。

在配置文件里加上签名相关的配置

Signature:
  Strict: true
  PrivateKeys:
    - Fingerprint: 6PZ+6+kq8CaH4q0k/9zqjg==
      KeyFile: etc/private.pem
  1. Strict: true 启用严格模式,此时签名不正确的请求,会返回 403 Forbidden
  2. 可以配置多套公私钥,对应于发给不同的客户端
  3. Fingerprint 其实是私钥的ID,go-zero 中推荐把它设置为公钥的 MD5 base64

如何请求

请求需要设置 X-Content-Security Header,示例内容为

详解 go-zero 的签名机制(图一)

其中

  1. key 为 fingerprint 让服务端知道用哪个私钥解密
  2. secret 为秘文
  3. signature 为签名

原理分析

详解 go-zero 的签名机制(图二)

上图说明如何计算 secretsignature,其中

  1. Time 为当前时间戳
  2. Key 为 32 字节随机数据
  3. 用公钥以 RSA 算法加密了 TimeKey
  4. 公钥无需在网络上传输

go-zero 在 contentsecurityhandler.go 中校验签名的算法

  1. 根据 fingerprint 找到服务端的私钥
  2. 使用私钥解密 secret
  3. 验证 secret 里的 Time 与服务器时间的误差在一定范围内。这一步防止了重放攻击
  4. 验证签名:也就是重新计算图中的绿色部分并用 secret 里的 Key 算出签名;与 signature 比较,必须相等。这一步防止了篡改攻击
  5. 解密消息体 (可选步骤,由 secret 里的 Type 决定):用 secret 里的 Key 以 AES 算法解密消息体,进入业务逻辑处理,完成后再加密响应消息体,发回客户端。这一步防止了抓包分析

如果客户端设置了消息体加密,则中间人抓包是这样的

详解 go-zero 的签名机制(图三)

图三与图一对比,很容易看出消息体加密后的效果。

总结

go-zero 的签名开关,可以用在系统为第三方开放接口的场景。此时用颁发给第三方的公钥来确定请求方的身份,信道传输上能防重放、防篡改、防抓包。

弊端是请求方需要按照 go-zero 的要求构造 X-Content-Security Header,有点复杂,系统应该提供 SDK 或者代码示例。Go 语言的示例可以参考 contentsecurityhandler_test.go ,如果你的客户端是 Android,可以关注本公众号留言获取没有任何外部依赖的纯 Java8 的请求示例代码。

参考资料
[1]

API 签名机制: https://go-zero.dev/docs/tutorials/api/signature

[2]

生成的命令: https://auth0.com/docs/secure/application-credentials/generate-rsa-key-pair

[3]

原因: https://stackoverflow.com/questions/2957742/how-to-convert-pkcs8-formatted-pem-private-key-to-the-traditional-format

[4]

旧格式的私钥: https://stackoverflow.com/questions/20065304/differences-between-begin-rsa-private-key-and-begin-private-key

原文始发于微信公众号(内存泄漏):详解 go-zero 的签名机制

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月22日13:52:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   详解 go-zero 的签名机制https://cn-sec.com/archives/3137496.html

发表评论

匿名网友 填写信息