官方教程在此:
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
第一部分是 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 小时,所以把时间戳换了自己重新计算吧。