api接口签名验证
由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsessionid)来辨别客户端的身份的,当客户端进行登录服务器也会将登录信息存放在服务器并与客户端的cookie中的jsessionid关联起来,这样客户端再次访问我们就可以识别用户身份了。
但是对于api服务器,我们不能让访问者先登录再进行访问这样不安全,也不友好。所以一般情况我们都是需要客户端提供一个key(每个key跟用户是一对一关联的)来识别请求者的身份。
由HTTP协议进行通信的数据大都是未经加密的明文,包括请求参数、返回值、 cookie、 head等等数据,因此,外界通过对通信的监听,轻而易举便可根据请求和响应双方的格式,伪造请求与响应,修改和窃取各种信息。所以我们还需要对每次请求进行认证,来判断发起请求的是不是就是该用户,以及请求信息是否被篡改。一般采用对请求信息(请求uri,参数)进行摘要的方法来解决上述问题。由于摘要算法的不可逆性,因此这种方式能够在一定程度上防止信息被篡改,保障通信的安全。
1、MD5方式
用户需要先在网站上申请key、secret,然后校验流程如下:
客户端:
1.参数排序
2.将参数串接起来加上secret,生成待摘要字符串
3.使用MD5等摘要算法生成摘要串signature
4.将key,signature放入header中一并传给服务器
服务器:
1.参数排序
2.将参数串接起来加上secret(通过header中的key在数据库获取),生成待摘要字符串
3.使用MD5等摘要算法生成摘要串
4.服务端生成的摘要串与客户端通过header传递过来的摘要串进行比较
2、HmacSHA256方式
用户需要先在网站上申请key、secret,然后校验流程如下:
客户单:
1.将请求参数封装成json字符串,也就是请求体body
2.使用HmacSHA256算法加secret对(请求url+nonce+body)加密生成摘要signature
3.将key,signature放入header中一并传给服务器
服务器:
1.获取请求中的请求体body字符串
2.使用HmacSHA256算法加secret(通过header中的key在数据库获取)对(请求url+nonce+body)加密生成摘要signature
3.服务端生成的摘要串与客户端通过header传递过来的摘要串进行比较
注意使用HmacSHA256更加安全,而且我们可以直接将请求参数封装成json字符串放入请求体中(也就是通过io流)进行传递。
实际使用中遇到的问题:
1、带有下划线的header被过滤
当我们在使用HmacSHA256进行认证的时候,需要客户端将请求key,signature放入header,name设置为api_key,api_signature,这时出现一个问题是服务器怎么都获取不到这两个值,但是我在本机测试时没有问题的。后来才想起来是不是由于使用nginx做集群而部分头被过滤了,查看过后果然是nginx将带有下划线的header
name过滤了,后来修改nginx配置便可以正常获取头信息。不过后来服务器使用了第三方的动态加速再次把带有下划线的header
name给过滤了,为了避免麻烦索性修改程序将header name中的下划线都去掉了。
2、确保每次请求唯一性
由于http都是明文请求,虽然我们可以通过摘要进行一定的安全保证确保信息不被篡改,但是我们无法保证每次请求的唯一性,也就是如果请求数据被别人获取再次请求,此时也可能带来很严重的安全性问题。于是我们便需要用户在每次请求中设置一个递增的参数nonce,来确保每次请求都是唯一的。不过这样也可能带来一个问题,就是如果用户近乎同时发起两个请求a
b,由于网络阻塞,可能后发起的b先到达服务器,这样当a达到的时候,服务器会认为a的nonce已过期请求非法而拒绝。为了解决这样的问题我们允许用户设置一个expire值来避免nonce认证带来的问题。
3、SNI
由于当时我们有不同的工程(不同的域名,跟不同的证书)位于同一台服务器,这样有的客户端访问我们api工程会抛异常,说http握手失败或者说请求域名与服务器证书不匹配而失败。所以我们需要客户端程序支持sni,它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。对于java语言来说jdk7的后续版本已经支持sni,或者使用httpclient
4.3及以后版本都可以很好的支持sni了。
api接口签名验证的更多相关文章
- 转载-常用API接口签名验证参考
原文地址: http://www.cnblogs.com/hnsongbiao/p/5478645.html 写的很好,就做个笔记了.感谢作者! 项目中常用的API接口签名验证方法: 1. 给app分 ...
- 常用API接口签名验证参考
项目中常用的API接口签名验证方法: 1. 给app分配对应的key.secret2. Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: a. 按照请求参数名称将所有请求参数按照 ...
- 开放api接口签名验证
不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...
- api接口签名验证(MD5)
不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...
- 【转】开放api接口签名验证
不要急,源代码分享在最底部,先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候, ...
- springcloud提供开放api接口签名验证
一.MD5参数签名的方式 我们对api查询产品接口进行优化: 1.给app分配对应的key.secret 2.Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下: a. 按照请求参数 ...
- API接口签名验证2
http://www.jianshu.com/p/d47da77b6419 系统从外部获取数据时,通常采用API接口调用的方式来实现.请求方和�接口提供方之间的通信过程,有这几个问题需要考虑: 1.请 ...
- 简单API接口签名验证
前言 后端在写对外的API接口时,一般会对参数进行签名来保证接口的安全性,在设计签名算法的时候,主要考虑的是这几个问题: 1. 请求的来源是否合法 2. 请求参数是否被篡改 3. 请求的唯一性 我们的 ...
- PHP 开发API接口签名验证
就安全来说,所有客户端和服务器端的通信内容应该都要通过加密通道(HTTPS)传输,明文的HTTP通道将会是man-in-the- middle及其各种变种攻击的温床.所谓man-in-the-midd ...
随机推荐
- iOS学习之设计模式
iOS开发学习中,经常弄不清楚ios的开发模式,今天我们就来进行简单的总结和探讨~ (一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现. 优势:解耦合 敏捷 ...
- java开发模式学习
1.瀑布模式 这种模式适合小项目,一层层进行编码,没有规模的设计, 2.原型模式 先做模板给客户在做实体 3.面向对象模式 用面向对象的思想进行开发 4.螺旋模式 从内到外一层层开,
- UE4 创建进程,打开额外程序 方法 笔记
FPlatformProcess::CreateProc(TEXT("程序路径");
- java 实现一个简易计算器
import java.util.Scanner;public class Test { public static void main(String[] args) { count(); } pub ...
- Error: unable to connect to node rabbit@mail: nodedown
某天,开启一个应用时,发现连接rabbitmq失败,本来想用rabbitmqctl来查看队列,结果提示“Error: unable to connect to node rabbit@mail: no ...
- linux驱动之触摸屏驱动程序
触摸屏归纳为输入子系统,这里主要是针对电阻屏,其使用过程如下 :当用触摸笔按下时,产生中断.在中断处理函数处理函数中启动ADC转换x,y坐标.ADC结束,产生ADC中断,在ADC中断处理函数里上报(i ...
- jQuery学习总结
1:jQuery是什么 jQuery是继prototype之后又一个优秀的Javascript框架.它是轻量级的js库,兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, O ...
- iOS 打电话 发短信(转载)
官方代码 发短息和邮件添加MessageUI.framework 库 发送信息 - (IBAction)showSMSPicker:(id)sender { // You must check tha ...
- 关于MySQL5.6.25在Win7 64bit下重装后无法启动的解决方法
在重装MySQL5.6.25安装到进行配置的时候,一直在等待服务的启动.如果手动在系统服务启动会提示1067错误,这个错误在网上很常见,然而我试过了很多方法均无法解决. 于是看ProgramData\ ...
- Arrays.asList()注意
api: public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表.(对返回列表的更改会“直接写”到数组.)此方 ...