Java 解密TLS 1.2 AES-GCM数据包

Java 解密TLS 1.2 AES-GCM数据包,java,ssl,encryption,bouncycastle,aes-gcm,Java,Ssl,Encryption,Bouncycastle,Aes Gcm,我正在开发一个Java程序来解密一个TLS1.2会话,该会话使用TLS\u RSA\u和\u AES\u 128\u GCM\u SHA256密码。我用wireshark录制了一个测试会话。主秘密已为人所知 No. Time Protocol Length Info 4 0.000124000 TLSv1.2 166 Client Hello 6 0.000202000 TLSv1.2 1074 Server Hell

我正在开发一个Java程序来解密一个TLS1.2会话,该会话使用
TLS\u RSA\u和\u AES\u 128\u GCM\u SHA256
密码。我用wireshark录制了一个测试会话。主秘密已为人所知

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
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
数据包11数据:

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
到目前为止我所做的:

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
密钥派生:

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
这里我只需要客户端密钥,因为我想解密一个Client->Server包。我根据RFC扩展了服务器和客户端密钥和IVs。

客户端写入密钥:4B119DFBFC930ABE1300BD53C3BF78
客户写入IV:2029CAE2

Nonce:

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
我从salt(=客户端写入IV)和显式nonce(=加密数据的前8字节)创建AES-GCM nonce。

盐:2029CAE2
明确一次:C91DE005E2AE50A8
暂时:2029CAE2C91DE005E2AE50A8

附加身份验证数据(AAD):

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
这就是我被卡住的地方。RFC5246说明:

附加数据=序号+TLSCompressed.type+ TLSCompressed.version+TLSCompressed.length; 其中“+”表示串联

所以我做了这个:

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
我认为
序号
是1。当发送
Change Cipher Spec
记录时,它被重置为零。(
Packet#8
)则加密的
完成的
记录具有
序号=0
。下一个客户端数据包是我们的
数据包#11
,带有
序号=1

代码:

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
现在我把所有东西都放进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;
    }
结论: 由于解密的输出是正确的,我可以安全地假设密钥派生和解密工作正常。只有身份验证失败。所以我想我可能在附加身份验证数据(AAD)方面做错了什么。 所以这个问题可以归结为:

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


谢谢大家!

GCM模式根据消息、相关数据和公共时态计算MAC,您已经很好地介绍了它

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