1. HMAC
HMAC: 基于哈希的消息验证码(Hash-based Message Authentication Code,HAMC),HMAC是一种消息验证码,用来验证消息的完整性和身份的真实性,它通过一个密钥和一个散列函数(比如SHA-256)对消息进行处理,相比单纯的哈希函数,HMAC具有更高的安全性,因为它依赖一个密钥,而不仅仅是消息内容。
常见的HMAC算法: HashSHA256、HmacSHA1、HmacMD5。
2. HmacSHA256
HmacSHA256: 基于SHA256的HMAC算法(Hash-based Message Authentication Code using SHA-256,HmacSHA256)。
HmacSHA256的作用:
- 数据完整性: 因为HMAC签名是用双方共享的密钥生成的,如果接收方计算的HMAC签名的值和发送方一致,表明数据在传输过程中没有被篡改。如在API认证过程中,对时间戳和共享密钥进行HMAC签名后,如果时间戳(作用防重放)被篡改,那接收方使用相同方法计算出的HMAC签名就不一样。
- 数据真实性: 由于HMAC需要密钥,只有知道密钥的客户端才能生成有效签名,因此服务器可以信任这个请求是来自合法客户端的。
HmacSHA256和SHA-256的区别:
3. HMAC与签名验签
为什么不使用非对称加密算法 + 消息摘要算法(如RSA + MD5)实现API请求认证:
- 计算效率:
HMAC-SHA256:是一种基于对称密钥的方案,计算效率高。生成和验证HMAC签名的速度比非对称加密的数字签名要快得多,适合高频请求和资源受限的场合,如API认证。
非对称签名:如RSA或ECDSA,计算密集度高。签名和验证都涉及复杂的数学运算,因此处理速度较慢。在每秒数千甚至数万次请求的高并发场景中,非对称加密的计算开销较大,可能导致延迟增加。
- 密钥管理:
HMAC-SHA256(对称密钥):在客户端和服务器之间共享一个密钥来生成和验证签名,没有私钥和公钥的区分,无需公钥分发,因此密钥管理相对简单,不过,共享密钥需要安全传输和存储。
非对称签名(公钥/私钥对):这种方式不需要双方共享密钥,服务器只需保存公钥即可验证客户端签名的合法性。但需要管理密钥对(公钥/私钥),使用私钥签名,公钥验证,并确保客户端妥善保管私钥,避免泄露。此外,若使用公钥基础设施(PKI),还需配合证书管理系统,增加了复杂度和运维成本。
- 抗重放攻击:
非对称签名:通常MD5签名会附带时间戳或随机数,以防止重放攻击。理论上,这种方法可以抵抗重放攻击,但实现起来较复杂,且在生成随机数或时间戳时需确保其不被篡改。
HMAC-SHA256:HMAC签名经常配合时间戳、随机数或一次性使用的“nonce”,在对称密钥环境下更容易抵抗重放攻击,同时实现简单。
更重要的: 客户端生成RSA密钥对,私钥用于生成签名,公钥用于服务器验证。将公钥安全地传输到服务器上存储,以便用来验证客户端签名。在实际应用中将公钥安全地传输到服务器上存储确实有难度,尤其是在大规模、多客户端的环境中,这一过程变得更加复杂。
- 密钥分发的安全性:将公钥从客户端传输到服务器的过程中,可能面临截获和篡改的风险,特别是在没有安全信道的情况下。
- 客户端身份验证:服务器需要知道哪个公钥属于哪个客户端。如果客户端很多,服务器需要建立一个安全、准确的公钥存储和管理机制,并与客户端身份进行映射。
- 密钥更新的复杂性:当客户端需要更新密钥(如密钥过期或遭到泄露)时,如何通知服务器更新公钥并验证新旧密钥的关系,是一个需要重点考虑的流程。
- 非对称密钥的存储和管理:对客户端而言,妥善存储私钥同样具有挑战性。若私钥泄露或丢失,可能导致身份伪造或认证失败。
4. API请求认证
API请求认证: 通过HMAC-SHA256生成的签名,服务器能够验证请求是否由合法的客户端发送,并且数据是否被篡改。在API请求中,HMAC签名机制通过生成一个签名(),让服务器可以验证请求的来源是否可信、内容是否未被篡改。签名通过一个双方共享的密钥(这里是)和时间戳计算出来。通常这种方法用在请求的认证头或查询参数中,以增强API的安全性。
API请求认证流程: 具体实现参照API-Mail-钉钉机器人部分。
假设你有一个API服务器和一个客户端应用程序,服务器在处理请求时需要验证请求的真实性。以下是具体的操作流程:
- 客户端生成签名并发送请求:
- 假设API服务器需要每个请求包含一个签名,以验证请求是否来自合法的客户端。
- 客户端获取当前时间戳,比如:。
- 客户端将时间戳和一个预定义的密钥(即双方已知的)生成一个待签名字符串(),对应的可能是:。
- 然后,客户端使用算法对该字符串进行加密,生成签名字节数组,并进行Base64编码和URL编码,假设生成的签名结果为:。
- 最后,客户端将该签名以及时间戳放入请求中发送给服务器。例如,这可能是一个GET请求:
- 服务器验证签名:
- 服务器接收到请求后,会获取其中的时间戳和签名。
- 服务器同样会使用相同的secret密钥,重新生成客户端的签名过程:
- 将时间戳和组成同样的。
- 使用加密生成签名字节数组。
- 对生成的字节数组进行Base64编码和URL编码,得到服务器计算出的签名。
- 服务器将计算出的签名与请求中传递的签名进行对比。如果一致,则表示该请求有效。
- 验证成功的意义:
- 数据完整性:因为HMAC签名是用双方共享的密钥生成的,若签名一致,表明数据在传输过程中没有被篡改。
- 请求来源真实性:只有知道密钥的客户端才能生成有效签名,因此服务器可以信任这个请求是来自合法的客户端。
- 过期时间的验证(防重放攻击):
- 通常,时间戳会设有过期时间,服务器只接受一定时间内的签名(比如5分钟内)。超过时间限制,签名会被认为无效,即使内容和密钥相同。
- 通过限制签名的有效时间,服务器能够抵御重放攻击,因为即便黑客拦截了签名,过期后也无法重复使用。
5. 长度扩展攻击
为什么需要进行两次哈希: HMAC的两次哈希设计主要为了安全性,增加抗攻击性和密钥隔离能力。在具体实现中,HMAC通过内外层填充和两次哈希有效防止了长度扩展攻击,并且使得HMAC在面对不同的哈希算法时都能提供稳健的安全保证。这些特性使得HMAC成为加密协议中广泛使用的消息认证码算法。
- 防止长度扩展攻击
- 提高密钥隔离性,避免密钥泄露:
- 直接对密钥和消息进行单次哈希容易暴露一些信息。如果单次哈希时消息过长,且每次哈希都用同一个密钥,可能导致攻击者通过已知的哈希结果分析出密钥。
- HMAC通过两次哈希,使用内外层填充常量(和)将密钥隔离起来。即便攻击者能够激活成功教程内层或外层的某一哈希,仍然难以获得原始密钥。
- 提高对不同哈希函数的通用性:
- HMAC最早被设计出来时,考虑到了不同的哈希算法(如SHA-1、SHA-256、MD5)都可以用作基础哈希算法。
- 通过两次哈希,HMAC的结构不依赖于某种特定哈希算法的实现,因此它在理论上对各种哈希算法都安全。
长度扩展攻击: 长度扩展攻击是一种针对基于Merkle-Damgård结构的哈希算法(如MD5、SHA-1、SHA-256等)的攻击方式。攻击者可以在已知哈希值和部分原始数据的情况下,通过附加内容来生成一个有效的哈希,从而伪造签名。
Merkle-Damgård结构简介:
- Merkle-Damgård结构是一种分块的哈希算法设计方法,将输入消息分成多个块,每一块依次输入到哈希函数中,并将上一次的哈希输出作为下一次的输入。
- 该结构的特性导致在已知中间状态的情况下,可以利用已知的哈希结果继续进行哈希计算,模拟追加内容,产生新内容的有效哈希。
长度扩展攻击的具体示例: 假设我们有一个哈希算法和一个服务器,该服务器用生成消息的签名。服务器端会将生成的签名和消息一起发送给客户端。攻击者可以利用这种机制伪造新的签名。
示例流程:
- 服务器生成签名
- 假设服务器有一个密钥(只有服务器知道)和一个消息(已知)。
- 服务器使用计算签名,并将结果作为签名发送给客户端。
- 比如,是字符串, 签名结果是(假设这是的输出)。
- 攻击者获得签名并伪造新消息
- 攻击者截获到这个签名和。
- 假设攻击者想要生成一个伪造的签名,但签名内容包括新的附加内容,比如。
- 攻击者并不知道,因此无法直接对进行哈希。但由于的Merkle-Damgård结构,攻击者可以在已知的基础上追加内容。
- 执行长度扩展攻击
- 攻击者通过一些数学操作,重新构造一个新的哈希输入,使得它相当于对的哈希计算。
- 由于SHA-256允许在中间状态继续追加哈希,因此攻击者可以在的基础上模拟一个追加运算,生成的哈希结果。
- 最终,攻击者生成了一个伪造的签名(假设这是的结果)。
- 伪造请求发送
- 攻击者将和伪造签名发送给服务器。
- 服务器使用相同的方法验证签名,由于生成方式相同,因此服务器会误认为这个签名是合法的。
为什么HMAC可以防止这种攻击: 在HMAC中,密钥参与了两次哈希计算。
- 内层哈希计算,再进行外层哈希。
- 由于密钥在外层哈希中再次混入,使得攻击者即便掌握内层哈希值,也无法继续追加伪造信息。这种结构防止了长度扩展攻击。
6. 重放攻击
重放攻击: HMAC(带密钥的哈希消息认证码)本身不能直接防止重放攻击,但它可以作为防止重放攻击的一个关键组成部分,尤其是当与时间戳或唯一标识(Nonce)结合使用时。下面具体讲解HMAC的作用和为什么它在防止重放攻击中有效。
结合HMAC、时间戳和Nonce防止重放攻击: 假设一个API请求中包含HMAC、时间戳和Nonce,以下是防止重放攻击的完整流程。
- 客户端生成带HMAC的请求:
- 步骤1:客户端生成请求消息(例如)。
- 步骤2:客户端在请求中加入一个时间戳(表示请求的发出时间)和一个唯一标识(一个随机字符串)。
- 步骤3:客户端使用共享密钥对消息、时间戳和Nonce生成HMAC签名。
- 步骤4:将消息、时间戳、Nonce和HMAC签名一起发送给服务器。
- 服务器验证请求:
- 步骤1:服务器接收到请求,提取出消息内容、时间戳、Nonce和HMAC签名。
- 步骤2:服务器验证时间戳,确保请求在有效时间范围内(例如,5分钟内的请求有效),若超时则拒绝请求。时间戳限制了请求的有效时间窗口,确保请求必须在一定的时间范围内发送。
- 步骤3:服务器检查是否在短时间内重复(通常会将存入数据库或缓存中,存储一段时间),若已存在,则认为是重放请求并拒绝。Nonce保证了请求的唯一性,即便时间戳在有效期内,每个请求也需要不同的,防止重复请求。
- 步骤4:服务器使用共享密钥重新计算HMAC签名并验证签名是否一致,以确保消息未被篡改。时间戳、Nonce和HMAC结合后,攻击者无法重用旧请求数据,也无法伪造新请求,从而防止了重放攻击。
- 请求处理与Nonce存储:
- 若验证通过,服务器处理请求并将存入缓存中(比如Redis)或数据库,记录短时间内已使用过的Nonce。
- 下次如果收到相同的,服务器会直接拒绝请求,因为这是一个重复的请求(重放攻击)。
nonce的失效时间的设置: 通常情况下,Nonce的存储时间与请求的有效时间窗口保持一致。也就是说,Nonce的有效存储时间和时间戳所限定的请求有效期通常相同。这样做可以确保请求的唯一性,同时节省存储资源和验证逻辑的复杂性。
防止重放攻击的一致性:
- 既然服务器要求请求必须在5分钟的时间窗口内有效,那么只需要在这5分钟内检查是否有重复的Nonce即可。
- 超过5分钟的Nonce可以安全地删除,因为即使攻击者重新发送此请求,时间戳也会超时导致请求无效。
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/56961.html