go-zero接口签名

发布时间:2023年12月17日

官方教程在此:
https://go-zero.dev/docs/tutorials/api/signature
先说问题,这个教程只说明了怎么开启签名,但是服务端如何设置参数,以及客户端怎么签名并没有说。如果你对这东西怎么真正的投入使用感兴趣,下面的示例可以完成这个目标。

前提

官方的快速开始根本没开始,因为你没有尝试过怎么校验。在以下步骤前,你应该按照官方示例生成了代码。

服务端配置解读

第一步:
在线生成工具:https://oktools.net/rsa
生成 RSA 密钥文件。这里给个固定可以用的。
私钥

-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAOZrxt6gzYNcospmcnKkvdvJXOxePmc5uUN03mAVBPlSIOhE4J8h
dpeV/Qc85xt3cqlWYQi5xCMEHTe6noiors8CAwEAAQJBAIoWLtD+VwsROfHH4XB4
79rGWuzAMe+UtUUKxbWZAykR/rcad0uaaqbu2Jdt+RGO8BRG+cMBSftOaEC4ssu9
wIECIQD5gDbXmqETn6DSC+noNNwk+VNq1PPemOjzMLtMR0JZQQIhAOxsVF0F30hV
S1I+xto4QmX8W7MPGgUVWcLAyMSCVHQPAiBgEvMLSsvD1rACsfu8Ir6yrh9k/+N4
T8FEA/vbf4UZAQIhANKgSCB/pMZ6RppFFz8+M9lMFB3X7GRu+wLIYZTAT6D9AiBP
MG5ZjPR0mT7cLst77hBTItFHf+aBNb1QhU1cEAPbVg==
-----END RSA PRIVATE KEY-----

公钥

-----BEGIN RSA PUBLIC KEY-----
MEgCQQDma8beoM2DXKLKZnJypL3byVzsXj5nOblDdN5gFQT5UiDoROCfIXaXlf0H
POcbd3KpVmEIucQjBB03up6IqK7PAgMBAAE=
-----END RSA PUBLIC KEY-----

第二步:
改项目配置文件,加上以下密钥配置:

Signature:
  Strict: true                   # 是否开启校验,调试的时候可以关掉,默认是关闭
  Expiry: 24h										 # 签名字段的过期时间,默认 1 h
  PrivateKeys:									 # 密钥以及指纹,密钥是上面 RSA 文件位置,指纹自定义,可以多组
    - Fingerprint: "aabb"
      KeyFile: ./secret/id_rsa

第三步:
启动服务端,至此服务端的事情就干完了。

客户端签名

加一个header
客户端组装一个 header,叫做:X-Content-Security。该header 包含多个部分:

  • key
  • secret
  • signature

什么是key
第一部分是 key,key 就是前面服务端配置的Fingerprint,原样写一下。

key=aabb

什么是secret
第二部分是 secret,secret 的意义是签名,避免被篡改,这里有type,取值范围为 0 或者 1,如果不了解,那就写 0。还有对key做base64转化的部分,最后的部分是 timestamp,举个例子type=0,key=aabb,时间戳是1702283986,那么待加密的字符串是如下:

type=0;key=YWFiYg==;time=1702283986

次序无所谓,对上面的字符串用公钥加密,公钥哪里来?就是上面生成的公私钥。公钥加密后应该会得到如下字符串:

HlevieWAA4tyfz9d7DJgX7rQq/9GCOx65bdpeANqxIKZkAPCj0i1jbIhlagJlm/11P3peqLDJe5X3pl+a15jLA==

第三部分是对请求的内容进行加密,举例,我的请求是:

curl --location ‘localhost:8888/sign/demo’ --data ‘{“msg”:“111”}’ -X POST

什么是signature
signature的加密签名如下:timestamp+method+path+query+sha256(body),每个参数之间用’\n’换行符分割,举例说明,这里timestamp=1702283986, method是POST,path是/sign/demo,query是空的

1702283986\nPOST\n/sign/demo\n\n2fa4e16a8581b6042567516d23d9df8274082712f05c56fff2f736e3e17d514f

最后那串是{“msg”:“111”}经过 sha256散列而来的。对上面的字符串做一个macbase64的对称加密,加密使用的key 还是上面的 aabb,也就是服务端配置的Fingerprint,得到如下:

MLnSCu6fo6X9kV/er/NbGfJKF/80By0geR/Qx/7y4hE=

至此得到了所有需要的参数,也就得到了最后的heder

key=aabb;secret=HlevieWAA4tyfz9d7DJgX7rQq/9GCOx65bdpeANqxIKZkAPCj0i1jbIhlagJlm/11P3peqLDJe5X3pl+a15jLA==;signature=MLnSCu6fo6X9kV/er/NbGfJKF/80By0geR/Qx/7y4hE=

得到这个 header 你还是无法请求成功,因为这个时间戳应该已经过期了,配置写着签名过期时间是 24 小时,所以把时间戳换了自己重新计算吧。

一些扩展

  • PrivateKeys是数组,这说明可以配置多套指纹和 rsa文件,这适合单服务多套加密的场景。
  • type 字段取值可以为 1,,1 的话是代表客户端对 body 做了加密处理,处理的方式是:先用 AES-ecb加密,key依然是上面配置的Fingerprint, 然后做base64转化,具体操作看源码,因为没有文档。
文章来源:https://blog.csdn.net/qq_37957829/article/details/134933878
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。