- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在开发一个 Java 程序来解密使用 TLS_RSA_WITH_AES_128_GCM_SHA256
密码的 TLS 1.2 session 。我使用 wireshark 录制了一个测试 session 。 Master Secret 已为人所知。
No. Time Protocol Length Info
4 0.000124000 TLSv1.2 166 Client Hello
6 0.000202000 TLSv1.2 1074 Server Hello, Certificate, Server Hello Done
8 0.001071000 TLSv1.2 393 Client Key Exchange, Change Cipher Spec, Finished
9 0.003714000 TLSv1.2 301 New Session Ticket, Change Cipher Spec, Finished
11 6.443056000 TLSv1.2 116 Application Data
12 6.443245000 TLSv1.2 765 Application Data
15 6.443390000 TLSv1.2 103 Alert (Level: Warning, Description: Close Notify)
数据包 11
包含一个我正在尝试解密的 HTTP GET 请求
。
握手数据:
Cipher: TLS_RSA_WITH_AES_128_GCM_SHA256
Client Random: 375f5632ba9075b88dd83eeeed4adb427d4011298efb79fb2bf78f4a4b7d9d95
Server Random: 5a1b3957e3bd1644e7083e25c64f137ed2803b680e43395a82e5b302b64ba763
Master Secret: 2FB179AB70CD4CA2C1285B4B1E294F8F44B7E8DA26B62D00EE35181575EAB04C
4FA11C0DA3ABABB4AF8D09ACB4CCC3CD
数据包 11 数据:
Direction is Client -> Server.
Secure Sockets Layer
TLSv1.2 Record Layer: Application Data Protocol: Application Data
Content Type: Application Data (23)
Version: TLS 1.2 (0x0303)
Length: 45
Encrypted Application Data: c91de005e2ae50a8a57abee55c183667b136343feef4a387cb7cf83030a47e230af268378c4f33c8b5bab3d26d
到目前为止我做了什么:
key 派生:
我在这里只需要客户端 key ,因为我想解密一个客户端->服务器包。我根据 RFC 扩展了服务器和客户端 key 和 IV。
客户端写入 key :4B119DFBFC930ABE130030BD53C3BF78
客户端写入 IV:2029CAE2
随机数:
我从盐(=客户端写入 IV)和显式随机数(=加密数据的前 8 字节)创建 AES-GCM 随机数。
盐:2029CAE2
explicitNonce:C91DE005E2AE50A8
随机数:2029CAE2C91DE005E2AE50A8
附加身份验证数据 (AAD):
这显然是我被卡住了的地方。 RFC5246 说:
additional_data = seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length; where "+" denotes concatenation.
所以我做了这个:
byte[] aad = {0, 0, 0, 0, 0, 0, 0, 1, // seq_no uint64
0x17, // type 0x17 = Application Data
0x03, 0x03, // TLS Version 1.2
0, 45}; // 45 Bytes of encrypted data
我认为 seq_no
是 1。当发送 Change Cipher Spec
记录时,它会重置为零。 (Packet #8
) 然后加密的Finished
记录有seq_no = 0
。下一个客户端数据包是我们的 Packet #11
,seq_no = 1
。
代码:
现在我将所有内容都输入 BouncyCaSTLe:
AEADParameters parameters = new AEADParameters(new KeyParameter(clientWriteKey), 128, nonce, aad);
GCMBlockCipher gcmBlockCipher = new GCMBlockCipher(new AESFastEngine());
gcmBlockCipher.init(false, parameters);
byte[] plainText = new byte[gcmBlockCipher.getOutputSize(cipherText.length)];
try {
int decLen = gcmBlockCipher.processBytes(cipherText, 0, cipherText.length, plainText, 0);
decLen += gcmBlockCipher.doFinal(plainText, decLen);
} catch (InvalidCipherTextException e) {
System.out.println("MAC failed: " + e.getMessage());
}
这总是会抛出 MAC 失败:GCM 中的 mac 检查失败。 但是解密输出是正确的:
byte[] decomp = decompress(plainText);
System.out.println(new String(decomp, "UTF-8"));
这会打印 GET/HTTP/1.0\n
。
解压助手:
public static byte[] decompress(byte[] data) throws IOException, DataFormatException {
Inflater inflater = new Inflater(true);
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
while (inflater.getRemaining() > 0) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();
inflater.end();
return output;
}
结论:由于解密的输出是正确的,我可以放心地假设 key 推导和解密工作正常。只有身份验证失败。所以我想也许我对附加身份验证数据 (AAD) 做错了什么。所以这个问题归结为:
附加身份验证数据 (AAD) 是如何正确组装的?
谢谢!
最佳答案
GCM 模式根据消息、关联数据和公共(public)随机数计算 MAC,您讲得很好。
我认为你使用的长度错误,它应该是加密和附加 MAC 之前的明文长度。尝试 45 - 8(显式随机数)- 16 (MAC) = 21。
关于java - 解密 TLS 1.2 AES-GCM 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28198379/
是否可以使用 OpenSSL 或其他工具通过 TLS 建立 TLS 连接? 如果可能,每个级别的证书是否需要不同? 最佳答案 这在理论上应该工作得很好,但我不能确定 OpenSSL 或其他东西是否会轻
在我的 java 代码中,我正在使用命令创建 SSL 上下文的一个实例 SSLContext ctx = SSLContext.getInstance("TLS"); 但是在我的 tomcat 服务器
在我的 java 代码中,我正在使用命令创建一个 SSL 上下文实例 SSLContext ctx = SSLContext.getInstance("TLS"); 但在我的 tomcat 服务器中,
范围:这是一个具有一个 channel 的网络,该 channel 由 3 个组织组成,每个组织 1 个 anchor 节点,每个组织 1 个 CA 和每个组织 1 个 MSP。 我在我的 Hyper
无法找到用于在 iis 上启用/禁用 tls 的特定设置。启用/禁用 ssl 是否与启用/禁用 tls 相同? 我浏览了一些博客,发现 SSL 是 TLS 的前身,旧版本的 SSL 已被弃用。但我无法
最近,我一直在为基于物联网的项目评估不同的 API 网关 (API GW) 选项。这样做的目的是找到一个足够好的解决方案来执行设备和 API GW 的相互 TLS (mTLS) 身份验证。 我尝试过的
几个月来,我的 Web 应用程序在不同版本的 IE/Firefox/Chrome 上运行良好。我的应用程序在 IIS 10.0 上运行。当我从 Windows 7 框 (IE 11.0.***) 中点
我有一个在 Java 7 上运行的 HTTPS 网络服务。我需要进行更改,以便此服务仅接受 TLS1.2 连接并拒绝 SSL3、TLS1.0 和 TLS1.1。 我添加了以下 Java 参数,使 TL
我在资源管理器不显示网站时遇到问题:“无法显示此页面。在高级设置中打开 TLS 1.0、TLS 1.1 和 TLS 1.2”。 我在 chrome 中调试了证书并说“连接是使用 aes_128_cbc
我正在与 5 个订购者、1 个组织和 2 个同行建立我的网络。还有 1 个 cli 和 1 个 ca。 我从 1 个排序者扩展到 5 个实现 Raft 的排序者。这就是为什么我想扩展我的网络并对多个对
当k8s集群开启了TLS认证后,每个节点的kubelet组件都要使用由kube-apiserver的CA签发的有效证书才能与kube-apiserver通信;当节点非常多的时候,为每个节点都单独签署证
我正在尝试使用 pjsip 安装中的 pjsua 程序在两个虚拟机之间进行安全调用。我通过以下方式在每个节点上启动程序: pjsua-x86_64-unknown-linux-gnu --use-tl
我开发的软件应用程序使用 gRPC 在客户端和服务器之间建立双向流。 我只在 java 中寻找类似于这张票的答案的东西:How to enable server side SSL for gRPC?
我正在尝试调试与 TLS 相关的问题。TLS 在两个应用程序客户端 A 和服务器 B 之间设置。A 和 B 都交换了证书,我已经验证证书具有正确的扩展名,并且还通过其根 CA 成功验证。叶证书的根 C
“Java 1.7 TLS 1.1 服务器”和“Java 1.8 客户端”之间的 SSL/TLS 握手在我的环境中失败,服务器端出现以下异常: java.security.NoSuchAlgorith
我正在尝试了解 Docker ,但我不断收到神秘的(对我而言)错误消息。 可能最简单的例子是尝试打印我安装的 Docker 版本: $ sudo docker version Client versi
这是我第一次使用 Amazon Lighsail、Wordpress Multisite、Bitnami甚至使用 Let's Encrypt;现在似乎一切正常,除了我的虚拟主机文件中的 SSL 指令。
我有一个 MariaDB "M"。在同一台机器上有一个应用程序“A”,它可以访问它。在不同的服务器上,另一个应用程序“B”也在访问它。 现在我想在 MariaDB 上启用 TLS 以保护连接 B ->
我正在寻找通过代理连接到一些 HTTPS/TLS 站点,其中到代理本身的连接也是通过 HTTPS/TLS 建立的,来自一个高度依赖请求的 python 应用程序。 urllib3(因此 request
现在我正在努力改变 EMQtt 和 Erlang MQTT 代理,以便我可以使用预共享 key 而不是非对称方法执行 TLS 握手。 到目前为止,我几乎遍历了源代码中的每个文件,但找不到任何加密函数。
我是一名优秀的程序员,十分优秀!