API在使用的时候往往都会有一些签名加密之类的东西,那么具体来说都有什么加密方式?签名方式又有啥呢?来看看API签名及加密方式详解,今天我们从专业的角度来进行全面解析,从技术角度对API的签名方式,加密方式等进行详解。
那么在文章开始之前呢,我们可以先来看看API集成管理,这个API集成管理平台集成管理是指在一个组织中管理和协调不同API的使用、开发和维护的过程。API允许不同的软件应用之间进行通信,从而实现数据和服务的共享。有效的API集成管理对于确保系统之间的顺利交互、提升开发效率以及保障数据安全至关重要,所以我非常推荐使用这个平台,可以更好的提高安全性。
下面开始解析API签名和加密方式
HTTP 简单身份认证
在 HTTP 请求的 Header 中添加认证字段例如:
Authorization: 3F2504E04F8911D39A0C0305E82C3301
服务器处理前取出该字段进行校验即可。
Spring Boot 直接实现一个拦截器可进行判断:
xml
<span class="hljs-type">String</span> <span class="hljs-variable">token</span> <span class="hljs-operator">=</span> request.getHeader(<span class="hljs-string">"Authorization"</span>);
<span class="hljs-keyword">if</span> (!Strings.isNullOrEmpty(token)) {
hasAuth = redisTemplate.hasKey(<span class="hljs-string">"userToken:"</span> + token);
}
这类方法实现比较简单,可以做基本的身份认证,防君子不防小人,可通过中间人攻击获得 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请求头中,一同发送至服务器。
看一下下面的图
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。
作者:幻城