不积跬步,无以至千里

http加签验签


http涉及安全相关的问题总会提到加签验签.

加签是指在原有的请求参数中添加一个数字签名(sign),这个签名使用特定算法根据原请求参数生成.服务端接收到请求之后,使用双方约定好的的算法,同样根据接收到的请求生成数字签名,比对生成的签名和接收到的请求中的签名是否一致,来判断请求参数是否被篡改过.通过这个过程也可以看出,加签验签的过程目的是防止请求参数在传递过程中被篡改.由于在这个过程中,请求参数明文传输,所以加签验签并不能防止请求参数被泄漏.

另外,由于参与加签验签的双方事先会商定一个加签验签的规则,所以也能确保只有指定的服务才可以向服务端发送请求.

数字签名的生成有很多方式. 以下介绍几种常见的加签算法和具体实践

如对一个Post请求,请求参数为{"method":"getOrder","orderId":"orderId1"}

对请求添加时间戳

在请求参数中需要添加时间戳,并将该时间戳参与加签验签,一方面避免请求被截获后,使用相同的请求参数非法重复请求,造成网络阻塞和系统压力;另一方面也避免了算法在有效时间内被破解

服务端接收到请求后,取出请求参数中的时间戳,如果距离当前时间超过一定时间(如3s),可以直接拒绝请求.

所以需要做加签的请求参数有:

method:"getOrder"
orderId:"orderId1"
timestamp:123456

secret

发送方和接收方共同保存一个相同的随机字符串(secret),双方约定一个规则将请求参数和secret共同拼成一个字符串,然后按照一个指定的算法生成字符串

  1. 怎么拼字符串? 一般会将请求参数按照字典序做排序,这样的目的是接收方拿到请求参数之后,按照这个规则拼成的字符串和发送方是相同的.方便后续接口请求参数的添加或修改. 按照这个规则对以上请求参数做拼接:method=getOrder&orderId=orderId1&secret=akfd3534jqker&timestamp=123456
  2. 生成字符串 对以上拼好的字符串做MD5加密:48064e68ed226d156702cad1c422db97

最后得到本次请求的请求参数为{"method":"getOrder","orderId":"orderId1","timestamp":123456,"sign":"48064e68ed226d156702cad1c422db97"}

md5rsa

md5rsa区别于secret的地方在于,发送方和接收方使用一个公私钥对来做加签验签.发送方使用私钥生成签名串,接收方对同样的字符串使用私钥生成签名串,接收方判断接收到的签名串和自己生成的签名串是否一样来判断是否验签通过.

rsa是非对称算法,加密的字符串越长,计算越复杂.所以在实践中,会首先对请求参数拼成字符串后做md5,生成一个摘要,然后对摘要做rsa加密.