请求数据包加签的分析
1 引言
在当今数字化的世界中,网络通信是应用程序之间进行数据交换的关键手段。然而,这种通信过程往往受到各种潜在的威胁,例如中间人攻击、数据篡改等。为了确保数据的完整性和安全性,许多应用程序采用了请求数据包加签的机制。
请求数据包加签 是一种通过数字签名确保数据传输安全的方法。它通过在数据包中嵌入数字签名,使接收方能够验证数据的完整性和源的可信性。然而,加签的实施并不是一劳永逸的安全措施,而是需要不断进行安全测试来评估其可靠性和抵御潜在威胁的能力。
在本文中,我们将深入探讨请求数据包加签的安全测试。我们将分析不同的加签程度,从无签名到有签名未混淆,再到半混淆和全混淆的情况。我们将研究安全测试的难度随加签程度的增加而增加的原因,并提供实际案例,以帮助开发者和安全测试工程师更好地保障应用程序的安全性。
2 加签验签流程
2.1 加签
「加签」:用Hash函数把原始报文生成报文摘要,然后用私钥对这个摘要进行加密,就得到这个报文对应的数字签名。通常来说呢,请求方会把「数字签名和报文原文」一并发送给接收方。
2.2 验签
「验签」:接收方拿到原始报文和数字签名后,用「同一个Hash函数」从报文中生成摘要A。另外,用对方提供的公钥对数字签名进行解密,得到摘要B,对比A和B是否相同,就可以得知报文有没有被篡改过。
3 加签验签的必要性
下面通过一个简单的例子来说明为什么需要加签和验签
3.1 场景描述
假设小A 和 小B 之间有一种通信方式,小A 发送一条消息给 小B,消息内容是一笔转账请求,包含了转账金额和接收方账户信息。小A 希望确保这条消息在传输过程中不被篡改,并且 小B 希望能够验证消息确实是由 小A 发送的。
3.2 不使用加签的情况
• 小A 发送消息给 小B,消息内容如下:
转账金额:¥100
接收方账户:小B的账户
• 消息在传输过程中被攻击者 小Y 截获并篡改,将转账金额修改为 ¥1000。
转账金额:¥1000
接收方账户:小B的账户
• 小B 收到被篡改的消息后,无法识别消息是否被篡改,因为没有办法确认消息的完整性和真实性。
3.3 使用加签的情况
• 小A 发送消息给 小B 之前,先对消息进行数字签名,其中 <数字签名> 是使用 小A 的私钥对消息内容进行签名生成的。
转账金额:¥100
接收方账户:小B的账户
Signature: <数字签名>
• 消息在传输过程中被攻击者 小Y 截获并篡改,将转账金额修改为 ¥1000,但小Y 无法修改数字签名,因为她不知道 小A 的私钥。
转账金额:¥1000
接收方账户:小B的账户
Signature: <数字签名>
• 小B 收到消息后,使用 小A 的公钥对数字签名进行验证。如果验证通过,说明消息没有被篡改。
通过数字签名,小B 可以确认以下信息:
消息的完整性:消息在传输过程中是否被篡改。
发送者的真实身份:消息确实是由 小A 发送的,因为只有 小A 拥有私钥能够生成对应的数字签名。
4 加签程度与测试难度对比
加签程度与安全测试难度之间存在紧密关系,不同的加签程度会对安全测试提出不同的挑战。以下是对比不同加签程度与安全测试难度的考虑。
编号 | 加签程度 | 测试难度 |
1 | 无签名 | ⭐️ |
2 | 有签名未混淆 | ⭐️⭐️ |
3 | 有签名半混淆 | ⭐️⭐️⭐️ |
4 | 有签名全混淆 | ⭐️⭐️⭐️⭐️ |
下面以登录页面为例,在登录口是否进行加签,影响登录爆破的结果为例
4.1 无签名
加签程度:无签名表示没有对数据进行签名的机制,数据完全明文。安全测试难度:安全测试难度较低,因为没有签名需要验证,但风险也相对较高,容易受到中间人攻击、数据篡改等威胁。
4.1.1 前端代码
前端无签名,可清晰查看登录逻辑,可进行中间人拦截数据包,重防及篡改
下图为浏览器源码,可看出登录逻辑
4.1.2 中间人拦截
这里使用中间人拦截数据包,并进行重放请求,发现功能可正常使用
4.1.3 安全测试
登录爆破破解成功
4.2 有签名但未混淆
加签程度:有签名,但签名内容较容易理解,没有进行混淆处理。安全测试难度:安全测试相对容易,因为签名的验证相对直接。主要关注签名算法的强度和密钥的安全性。
4.2.1 前端代码
将用户名和密码进行加签并发送后端,可以清晰看到 加密的密钥:1234567890abcdefghijk
4.2.2 中间人拦截
中间人拦截数据包,未篡改用户名,可以正常发送数据包
篡改登录的用户名,提示签名失败,无法修改数据
4.2.3 安全测试
利用公开的算法,和前端获取到的密钥进行加密,获取到密码和签名的对应值,可再次进行登录爆破
import hmac
import hashlib
import base64
secret_key = b'1234567890abcdefghijk' # 密钥
username = 'admin'
password = ['123','111111','123456'] #密码字典
for i in password:
#拼接字符串
data_to_sign = username + str(i)
#进行加密
hmac_result = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest()
#转化成base64
result = str(base64.b64encode(hmac_result).decode())
#打印密码和sign的对应值
print(i+'t'+result)
###输出结果
123 2NIRgXmkmbuoOk0WwaLJ8nS7mcuUAWtOfXK282+YtqQ=
111111 ROrJKEaG/mdUAyhDemC+5vjBD+BRKvcf4HQEEsiUL+E=
123456 oUiVql5Crumyt7c2K9XxQ6y/4oXqs4oTMyj2Ua19YsU=
使用对应值,发现登录爆破成功
4.3 有签名但半混淆:
加签程度:有签名,签名内容经过一定程度的混淆处理,使攻击者难以直接理解签名的结构。安全测试难度:难度适中,需要考虑混淆算法的复杂性和对抗攻击者的能力。可能需要更深入的分析和测试。
4.3.1 前端代码
加签调用逻辑,加密函数采用了混淆的加密函数,可以看到存在部分固定的字符串
4.3.2 中间人拦截
中间人拦截数据包,存在签名的字符串
4.3.3 安全测试
加签的函数存在混淆,需要还原函数比较麻烦,普通业务系统的JS代码至少几十行,此时我们直接使用nodeJS直接调用函数,不管加签函数的内部的逻辑 有两种方法:
• (1)Chrome 控制台调用生成字典
• (2)使用NodeJS 配合mitmproxy自动运算
这里以第(1)种方法为例:Chrome 控制台调用生成字典 通过直接调用下列函数,发现可以得到加签后的值,每次运算都是相同,证明是密钥是静态固定的
输入:signEncrypt("admin",'123')
输出:2NIRgXmkmbuoOk0WwaLJ8nS7mcuUAWtOfXK282+YtqQ=
---------------------------------------------------------
输入:
var username ='admin';
var passwords = ['123','111111','123456','admin'];
for(var i = 0; i < passwords.length; i++) {
console.log("密码:"+passwords[i]);
console.log("对应的加签值:"+signEncrypt(username,passwords[i]));
}
---------------------------------------------------------
输出:
密码:123
对应的加签值:2NIRgXmkmbuoOk0WwaLJ8nS7mcuUAWtOfXK282+YtqQ=
密码:111111
对应的加签值:ROrJKEaG/mdUAyhDemC+5vjBD+BRKvcf4HQEEsiUL+E=
密码:123456
对应的加签值:oUiVql5Crumyt7c2K9XxQ6y/4oXqs4oTMyj2Ua19YsU=
密码:admin
对应的加签值:oMHE1DblMtlUDKofL8dFc+xNvhwqoZSlM3OhCpoaG3o=
将构造好的字典,加载进Burpsuite(拦截数据包工具、类似postman)工具,测试发现登录爆破成功
4.4 有签名全混淆:
加签程度:签名内容经过高度混淆处理,使其难以分析和破解。安全测试难度:高度难度,需要深入研究混淆算法,模拟攻击尝试破解。可能需要更高级的安全测试技术和工具。
4.4.1 前端代码
加签逻辑完全乱序,无法定位具体的函数
4.4.2 中间人拦截
采用工具拦截流量包,虽然可以拦截到请求,但无法构造参数signature的值
4.4.3 安全测试
(1) 使用在线反混淆工具,还原部分代码 在线网站:https://dev-coco.github.io/Online-Tools/JavaScript-Deobfuscator.html
(2)使用chrome 调试,下断点查看变量值,比较麻烦,需要看一定的运气还原代码
5 结语
因此,结合请求数据包加签的分析,我们要时刻谨记:安全是相对的,只有通过不断增加安全测试的难度,我们才能更好地守护着数字世界的安全之门。这是一场不断升级的战斗,我们的目标是不断提升我们的安全防线,让数字生活更加安心、可靠。
6 参考地址
• JS在线混淆地址:可对JS代码进行混淆,提供多种配置 https://www.json.cn/json/jshx.html
• JS在线反混淆地址:可对混淆后的代码进行还原,但只能还原部分代码 https://dev-coco.github.io/Online-Tools/JavaScript-Deobfuscator.html
• javascript-obfuscator :
是一个用于对 javascript 源码进行混淆的工具。它通过添加混淆内容、转换原始代码等方式,增加还原或阅读难度、乃至无法还原或阅读,从而达到保护我们的 javascript 代码的效果。此外,通过减少一些空格、注释可以加快代码运行的速度。https://github.com/javascript-obfuscator/javascript-obfuscator
相关代码可关注公众号,发送消息“data_signature_demo”,获取相关代码