在设计开放平台接口过程中,往往会涉及接口传输安全性相关的问题,加上之前面试中也被问到项目中开放平台的安全相关问题,因此有时间整理下思路,对于接口加密及签名的相关知识做了一个系统性的总结
开放平台API接口加密,签名策略
参考各大平台策略
支付宝
支付: appid+ PrivateKey私匙
转账+退款:1.RSA2(非对称)公匙加密 2.根证书 3.应用公匙证书
func (s *transferAccountService) newClient() *alipay.Client {
client, err := alipay.New(conf.AliPayAppID, conf.AliPayPrivateKey, true)
if err != nil {
panic(err)
}
if err := client.LoadAppPublicCertFromFile(fmt.Sprintf("appCertPublicKey_%s.crt", conf.AliPayAppID)); err != nil {
panic(err)
}
_ = client.LoadAliPayRootCertFromFile("alipayRootCert.crt")
_ = client.LoadAliPayPublicCertFromFile("alipayCertPublicKey_RSA2.crt")
return client
}
微信
支付: MCHID(实物商户号)+APIKey 必须
- 小程序支付和微信支付
1.都需要设置参数的paySign签名, 2.设置timestamp验证请求是否过期 - h5
则不需要
退款:1.商户API证书
func (s *RefundService) newClient() *wxpay.Client {
account := wxpay.NewAccount(s.AppId, conf.MCHID, conf.APIKey, false)
account.SetCertData("apiclient_cert.p12")
return wxpay.NewClient(account)
}
签名的概念与方法
2.1 为什么要签名?
1) 在客户端与服务器进行交互时,报文虽然加密了,但我们并不能确认这个报文是谁发过来的。例如,与第三方服务器B进行交互时,我方收到了一个已加密的请求,但我方并不能确认是服务器B发送的这个报文,此时我们可以用数字签名的方式来进行验证。作用:认证数据来源
2) 如果我方收到一个B服务器签名的请求,那么B服务器也无法否认这个请求,因为带有它的签名,作用:抗否认性。
3) 我方收到一个B服务器签名的请求,但我方并不能确认这个请求是否被篡改过(虽然报文加了密,也可能被篡改),此时即可用签名,验证签名中的报文与传过来的报文是否一致。作用:保证了数据的完整性
2.2 签名算法过程
签名的方式多种多样,常见的形式如下:
2.2.1 APPKEY+签名认证
1) 对除签名外的所有请求参数按key做的升序排列,value无需编码。(假设当前时间的时间戳是12345678)
例如:有c=3,b=2,a=1 三个参,另加上时间戳后, 按key排序后为:a=1,b=2,c=3,_timestamp=12345678。
2) 把参数名和参数值连接成字符串,得到拼装字符:a1b2c3_timestamp12345678
3) 用申请到的appkey 连接到接拼装字符串头部和尾部,然后进行32位MD5加密,最后将到得MD5加密摘要转化成大写。
示例:假设appkey=test,md5(testa1b2c3_timestamp12345678test),取得MD5摘要值 C5F3EB5D7DC2748AED89E90AF00081E6 。
风险在于一但appkey被别人获取,即可仿照签名,造成安全性问题
2.2.2 token+签名认证
token+签名认证的主要原理是:
1) 做一个认证服务,提供一个认证的webapi,用户提交相关身份信息如供应商编码,先访问它
2) 服务端收到请求,去验证相关身份信息,验证成功后,服务端会签发一个token,token一般可以存储在缓存或数据库中,以方便后面查询出来进行验证。再把这个 Token 发送给客户端
3) 客户端收到 token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;客户端每次向服务端请求资源的时候拿着相应的token以及请求的参数和服务器端提供的签名算法计算出签名后再去访问指定的api
6,服务端收到请求,就获取对应用户的token和请求参数,服务器端再次计算签名和客户端签名做对比,如果验证通过则正常访问相应的api,验证失败则返回具体的失败信息
安全的关键在于参与签名的token,整个过程中token是不参与通信的,所以只要保证token不泄露,请求就不会被伪造。然后我们通过timestamp时间戳用来验证请求是否过期,这样就算被人拿走完整的请求链接也是无效的
2.2.3 https模式
追求安全可以考虑https的双向验证模式 + 参数的sign签名的规则双重验证达到安全的请求后台
|