博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python使用json web token (jwt)实现http api的加密传输
阅读量:2444 次
发布时间:2019-05-10

本文共 3108 字,大约阅读时间需要 10 分钟。

CSRF攻击原理图:

20150119003530_89131.jpg

上图中Browse是浏览器,WebServerA是受信任网站/被攻击网站A,WebServerB是恶意网站/攻击网站B。

  • 一开始用户打开浏览器,访问受信任网站A,输入用户名和密码登陆请求登陆网站A。
  • 网站A验证用户信息,用户信息通过验证后,网站A产生Cookie信息并返回给浏览器。
  • 用户登陆网站A成功后,可以正常请求网站A。
  • 用户未退出网站A之前,在同一浏览器中,打开一个TAB访问网站B。
  • 网站B看到有人方式后,他会返回一些攻击性代码。
  • 浏览器在接受到这些攻击性代码后,促使用户不知情的情况下浏览器携带Cookie(包括sessionId)信息,请求网站A。这种请求有可能更新密码,添加用户什么的操作。

    从上面CSRF攻击原理可以看出,要完成一次CSRF攻击,需要被攻击者完成两个步骤:

    1. 登陆受信任网站A,并在本地生成COOKIE
    2. 在不登出A的情况下,访问危险网站 B。

    看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

    1. 你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
    2. 你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了……)
    3. 上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

现在常见的csrf防御是有那么几种方式:

  • 一种是在表单加上随机token串,这种能够避免99%的CSRF攻击,还有1%就是首先没有XSS攻击。
  • 一种是附加token的基础上加了refer的来源判断,
  • 还有一种是XMLHttpRequest的请求的方式,他可以不用在表单里面加header,但是问题来了,如果你的网站以前经常用的时动态加载的数据,也就是ajax方式加载的,那么很容易用XMLHttpRequest在请求体里面加上先前respone返回token
  • 每次表单请求都带验证码,对于用户体验这是万万不能的。我相信会让用户疯掉的。

现在我们来看看HTTP api有哪几种认证方式,首先要明白,认证和鉴权是不同的。认证是判定用户的合法性,鉴权是判定用户的权限级别是否可执行后续操作。这里所讲的仅含认证。认证有如下几种方法:

  1. 第一个是使用在HTTP规范中的Basic Auth,这个配置也是相当的简单,原理是在每个请求的header中添加用户名和密码的字符串(格式为“username:password”,用base64编码)。但是这种方式安全性较低,就是简单的将用户名和密码base64编码放到header中。 base64编码前:Basic admin:adminbase64编码后:Basic YWRtaW46YWRtaW4=放到Header中:Authorization: Basic YWRtaW46YWRtaW4=。正是因为是简单的base64编码存储,切记切记在这种方式下一定得注意使用ssl,不然就是裸奔了。 在某些产品中也是基于这种类似方式,只是没有使用apache的basic机制,而是自己写了认证框架,原理还是一样的,在一次请求中base64解码Authorization字段,再和认证信息做校验。很显然这种方式有问题,认证信息相当于明文传输,另外也没有防暴力破解功能。

  2. 第二个API Key是客户端从服务端签收一个加密的key,然后自己通过一定的算法组合加密数据,服务端会根据你的来源解析key。类似:

client

Paste_Image.png

Server

Paste_Image.png

client端向服务端注册,服务端给客户端发送响应的api_key以及security_key,注意保存不要泄露,然后客户端根据api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一个hash值sign,构造途中的url发送给服务端。 服务端收到该请求后,首先验证api_key,是否存在,存在则获取该api_key的security_key,接着验证timestrap是否超过时间限制,可依据系统成而定,这样就防止了部分重放攻击,途中的rest_api是从url获取的为/rest/v1/interface/eth0,最后计算sign值,完之后和url中的sign值做校验。这样的设计就防止了数据被篡改。 通过这种API Key的设计方式加了时间戳防止了部分重放,加了校验,防止了数据被篡改,同时避免了传输用户名和密码,当然了也会有一定的开销。

3 第三种是OAuth(或者OAuth2)。OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP Digest身份认证相比,安全性更高。使用和配置都比较复杂,这里就不涉及了。

4 第四种就是Token的机制。 在各种客户端上每次都让用户提交用户名和密码,这有些不合理的。 通常的情况是客户端通过一些可靠信息和服务器交换取token,这个token作为客服端再次请求的权限钥匙,当然token也是存在有效时间控制的。 Token通常比密码更加长而且复杂。那么一旦获得了token,在每次调用API的时候都要附加上它。这仍然比直接发送账户和密码更加安全,哪怕是HTTPS。把token想象成一个安全的护照。你在一个安全的前台验证你的身份(通过你的用户名和密码),如果你成功验证了自己,你就可以取得这个。当你走进大楼的时候(试图从调用API获取资源),你会被要求验证你的护照,而不是去前台重新验证。

5 第五种,JWT协议似乎已经应用十分广泛,JSON Web Token——一种基于token的json格式web认证方法。JWT是一段被base64url编码过的字符序列,并用点号分隔。它由三部分组成,头部header、载荷playload与签名sign。 服务端和客户端都可以通过secret_key来识别信息是否被串改过。其基本的原理是,第一次认证通过用户名密码,服务端签发一个json格式的token。后续客户端的请求都携带这个token,服务端仅需要解析这个token,来判别客户端的身份和合法性。在这里JWT是用来取代服务端的Session而非客户端Cookie的方案,当 然对于客户端本地存储,HTML5提供了Cookie之外更多的解决方案(localStorage/sessionStorage),究竟采用哪种存储 方式,其实从Js操作上来看没有本质上的差异,不同的选择更多是出于安全性的考虑。

具体算法如下图:

Paste_Image.png
JWT的主要应用场景

身份认证

在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。

信息交换

在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

作者:Moc木壳
链接:http://www.jianshu.com/p/6b6dc558353a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
你可能感兴趣的文章
如何在Microsoft Word中按字母顺序排列列表和表
查看>>
outlook附件提醒_在Outlook 2010中启用提醒铃声
查看>>
轻松将图像上传到Photobucket
查看>>
如何在Excel 2007中创建数据透视表
查看>>
如何在iPhone或iPad上启用USB受限模式(适用于iOS 11.4.1)
查看>>
注意:浏览器崩溃的技术支持弹出窗口又回来了
查看>>
如何在Ubuntu 11.10中安装Classic Gnome桌面
查看>>
下载HTG摄影备忘单(钱包大小!)
查看>>
有声读物制作_如何返回有声读物
查看>>
python识别音乐歌曲_如何轻松识别您正在听的歌曲
查看>>
ubuntu安装lxde_如何在Ubuntu上安装轻量级LXDE桌面
查看>>
photoshop使用技巧_如何使用Photoshop创建逼真的漫画
查看>>
windows全局热键_适用于Windows PC的20种最佳快捷方式和热键提示
查看>>
ubuntu tweak_如何使用Ubuntu Tweak自定义Ubuntu
查看>>
音色 特征选择_Google助手有六种新音色可供选择,现已推出
查看>>
三星健康权限_三星健康能做什么?
查看>>
oculus go_如何在Oculus Go上查看或清除浏览器历史记录
查看>>
热键打开程序_秘密热键在任何应用程序中打开Windows 10的新表情符号选择器
查看>>
如何更改Windows Photo Viewer的背景颜色
查看>>
如何在Windows 8中将IMAP电子邮件帐户添加到邮件应用程序
查看>>