解密TLS 1.2 AES-GCM数据包 [英] decrypt TLS 1.2 AES-GCM packet

查看:355
本文介绍了解密TLS 1.2 AES-GCM数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java程序解密 TLS 1.2 会话,该会话正在使用 TLS_RSA_WITH_AES_128_GCM_SHA256 密码。我使用Wireshark录制了一个测试会话。 主密钥是已知的。

I'm working on a Java program to decrypt a TLS 1.2 Session which is using the TLS_RSA_WITH_AES_128_GCM_SHA256 cipher. I recorded a test session using wireshark. The Master Secret is known.

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请求

Packet 11 Contains a HTTP GET Request that I'm trying to decrypt.

握手数据:

Cipher:        TLS_RSA_WITH_AES_128_GCM_SHA256
Client Random: 375f5632ba9075b88dd83eeeed4adb427d4011298efb79fb2bf78f4a4b7d9d95
Server Random: 5a1b3957e3bd1644e7083e25c64f137ed2803b680e43395a82e5b302b64ba763    
Master Secret: 2FB179AB70CD4CA2C1285B4B1E294F8F44B7E8DA26B62D00EE35181575EAB04C
           4FA11C0DA3ABABB4AF8D09ACB4CCC3CD

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

到目前为止已完成:

What I have done so far:

密钥派生:

我这里只需要客户端密钥,因为我想解密客户端->服务器包。我根据RFC扩展了服务器和客户端密钥以及IV。

客户端写密钥:4B119DFBFC930ABE130030BD53C3BF78
客户端写IV:2029CAE2

I only need Client keys here, as I want to decrypt a Client->Server package. I expanded server and client keys and IVs as per RFC. Client Write Key: 4B119DFBFC930ABE130030BD53C3BF78 Client Write IV: 2029CAE2

Nonce:

我从salt(= Client Write IV)和显式随机数(=头8字节)创建AES-GCM随机数加密数据)。

盐:2029CAE2
显露性:C91DE005E2AE50A8
显色性:2029CAE2C91DE005E2AE50A8

I create AES-GCM nonce from salt (=Client Write IV) and explicit nonce (=first 8 Byte of encrypted data). Salt: 2029CAE2 explicitNonce: C91DE005E2AE50A8 Nonce: 2029CAE2C91DE005E2AE50A8

其他身份验证数据(AAD):

这显然是我遇到的问题。 RFC5246表示:

This is where I apparently got stuck. The RFC5246 says:


additional_data = seq_num + TLSCompressed.type +
TLSCompressed.version + TLSCompressed.length;
,其中 +表示连接。

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 记录后,它将重置为零。 (数据包#8 ),然后加密的已完成记录具有 seq_no = 0 。下一个客户端数据包是我们的数据包#11 ,其中 seq_no = 1

I think seq_no is 1. It gets reset to zero, when Change Cipher Spec record is sent. (Packet #8) Then the encrypted Finished record has seq_no = 0. And the next client packet is our Packet #11 with seq_no = 1.

代码:

现在,我将所有内容都输入BouncyCastle:

Now I'm feeding everything into 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检入失败但是解密的输出是正确的:

This always throws MAC failed: mac check in GCM failed. BUT the decrypted output is correct:

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;
    }

结论:
如解密的输出是正确的,我可以放心地假设密钥派生和解密工作正常。仅身份验证失败。因此,我认为我可能在使用其他身份验证数据(AAD)做错了。
因此,这个问题可以归结为:

Conclusion: As the decrypted output is correct, i can safely assume that key derivation and decryption are working fine. Only authentication fails. So I think maybe I'm doing something wrong with the Additional Authentication Data (AAD). So this question boils down to:

如何正确组装附加身份验证数据(AAD)?

谢谢!

推荐答案

GCM模式根据消息,关联数据和公共随机数计算MAC

GCM mode computes MAC from message, associated data and public nonce, you covered it very well.

我认为您使用了错误的长度,在加密和附加MAC之前,它应该是纯文本长度。尝试45-8(显式随机数)-16(MAC)= 21。

I think you are using wrong length, it should be plaintext length before encrypting and appending MAC. Try 45 - 8 (explicit nonce) - 16 (MAC) = 21.

这篇关于解密TLS 1.2 AES-GCM数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆