API 签名及加密方式详解
![API签名及加密方式详解](https://static001.geekbang.org/infoq/87/87a6a0256d39d4d34d6521f7cfc16013.png)
API 在使用的时候往往都会有一些签名加密之类的东西,那么具体来说都有什么加密方式?签名方式又有啥呢?来看看 API 签名及加密方式详解,今天我们从专业的角度来进行全面解析,从技术角度对 API 的签名方式,加密方式等进行详解。
那么在文章开始之前呢,我们可以先来看看API集成管理,这个 API 集成管理平台集成管理是指在一个组织中管理和协调不同 API 的使用、开发和维护的过程。API 允许不同的软件应用之间进行通信,从而实现数据和服务的共享。有效的 API 集成管理对于确保系统之间的顺利交互、提升开发效率以及保障数据安全至关重要。
下面开始解析 API 签名和加密方式
HTTP 简单身份认证
在 HTTP 请求的 Header 中添加认证字段例如:
服务器处理前取出该字段进行校验即可。
Spring Boot 直接实现一个拦截器可进行判断:
这类方法实现比较简单,可以做基本的身份认证,防君子不防小人,可通过中间人攻击获得 Authorization。使用 HTTPS 安全性会得到提高,但是无法抵御重放攻击造成的影响,例如 DDOS,我们这里来分析一下会遭受什么攻击?怎么实现攻击手法
中间人攻击(MITM)
在非加密的 HTTP 连接上,任何在网络路径上的攻击者都可以截取和读取请求和响应的内容。这意味着如果Authorization
头包含的是纯文本的用户名/密码组合或者是一个静态令牌,攻击者可以轻松地获取这些信息,并在后续的请求中重用它们来冒充合法用户。
重放攻击(Replay Attack)
即使使用 HTTPS 来加密通信,静态的认证令牌仍然容易受到重放攻击。在这种攻击中,攻击者不是截取和解密数据,而是简单地记录下一次成功的认证请求,然后重复发送这个请求来访问资源。这是因为静态令牌在一段时间内保持不变,所以攻击者可以多次使用同一个令牌
API 签名认证流程
Part 1: 请求端加密
请求端加密是说,比如我对你说话,那么我是请求端,是我这里说话的时候进行加密,把我说的话加密一下再说给你,而你是服务端
秘钥分发:服务器向 API 使用者提供一对密钥,即 AK(Access Key)和 SK(Secret Key)。AK 是公开的,而 SK 需要保密,因为它是用于生成签名的密钥。
签名规则:HTTP Header:请求头中包含 AK,这允许服务器验证请求来自已注册的用户。参数排序与拼接:对于 GET 请求,所有参数按照 key 进行字典排序,并拼接成字符串;对于 POST 请求,根据不同的 Content-Type 进行相应处理。签名计算:使用 HMAC-SHA256 算法,以 SK 作为密钥,对拼接后的字符串进行签名,然后将签名结果 base64 编码。
请求构造:将 X-Ca-Key(即 AK)和 X-Ca-Signature(即签名)添加到 HTTP 请求头中,一同发送至服务器。
看一下下面的图
![](https://static001.geekbang.org/infoq/0c/0c09db95b7cf388aad663b53785f43e0.png)
Part 2: 服务器端验证
刚才我说道服务端是你,请求端是我,还用这个举例子,我把话说给你之后然后你是服务端,我加密了,说给你的话是加密的,这时候你需要验证并解密我说的话才行,那么是服务端解密和验证
验证 AK:服务器收到请求后,首先检查请求头中的 AK,确认请求者身份。
重新计算签名:服务器使用相同的算法和 SK 重新计算签名,以验证请求的完整性和一致性。
比较签名:将计算出的签名与请求头中的签名进行对比。如果匹配,则认为请求有效;如果不匹配,则拒绝请求,因为可能存在数据篡改或非授权访问。
防御重放攻击
主要防的是你 burpsuite 抓包重放,有了这个验证你想着通过 bp 抓包重放进行攻击,抱歉不可能了,因为会验证和加密,你抓包后在放包的时候会出现验证不过,会丢弃你那个包,到最后实现防御你这个攻击。API 签名机制可以通过加入时间戳和 nonce(一次性随机数)来进一步增强安全性,以防御重放攻击。时间戳和 nonce 都会被包含在签名计算中,且每个请求的时间戳和 nonce 都应该唯一。服务器会检查时间戳,确保请求没有过期,并且会跟踪 nonce,以避免处理重复的请求。
为了提高安全性,通常会结合使用 timestamp(时间戳)和 nonce(一次性随机数),以防止重放攻击(replay attack)。下面我进行全面的讲解
Timestamp 和 Nonce 的作用
Timestamp:这是请求发出的时刻,通常精确到毫秒。服务器会检查这个时间戳,如果与当前时间相差超过预设的阈值,认为请求过期,不予处理。这有助于防止攻击者捕获旧的请求并稍后重放,这个时间戳大家学过 linux 应该知道,不是单纯一个时间而是一长串数字,可以转换时间,用这个验证也是说双方必须用标准时间,不能出现时间误差,不然可能出现第一次请求验证不过,因为两个人时间不一样,所以需要用到 ntp 时间服务器同步时间。
Nonce:这是一个随机数,每次请求都不同。服务器会存储最近收到的 nonce,当接收到新的请求时,会检查这个 nonce 是否已经被使用过。如果 nonce 是新的,那么请求被认为是有效的;如果 nonce 已经存在,那么这可能是一个重放攻击。
使用 Timestamp 和 Nonce 的挑战
Nonce 的存储:随着请求量的增加,服务器需要存储越来越多的 nonce,这可能导致内存压力。通常,使用如 Redis 这样的键值存储系统来管理 nonce,它可以设置过期时间(TTL),这样旧的 nonce 会自动被删除。
API 签名与 HTTPS 的关系
我们讲到这里会有人询问,这个 API 签名加密和 https 是不是一回事?直接用 https 加密不行了还搞那么麻烦那么多事情干嘛?抱歉,这里我要说的是,不是一个概念,甚至这两个东西不是同样的东西,https 是传输层的一个加密,和 API 签名不在同一层,我来进行一下解析。
HTTPS:提供了传输层的安全,确保数据在网络上传输时不会被窃听或篡改。但是,HTTPS 本身并不提供对请求的验证或重放攻击的防护所以只是单单用一个 https 加密不太行,还得增加 API 签名。
API 签名:在应用层上保证了请求的完整性和来源的真实性,防止数据被篡改,同时也可以防止重放攻击。
结合 HTTPS 和 API 签名,可以提供更全面的安全保障,既保护了数据在传输过程中的安全,也确保了到达服务器的请求是合法且未被篡改的。在实际部署中,这是推荐的做法,尤其对于涉及敏感数据和交易的 API。
作者:幻城
版权声明: 本文为 InfoQ 作者【幂简集成】的原创文章。
原文链接:【http://xie.infoq.cn/article/2ed23cdbc0970bcd7da14e2ba】。文章转载请联系作者。
评论