Php 如何解密HTTPS(ECDHE)数据?

Php 如何解密HTTPS(ECDHE)数据?,php,encryption,https,elliptic-curve,diffie-hellman,Php,Encryption,Https,Elliptic Curve,Diffie Hellman,我正在努力了解HTTPS的工作原理,并做一些实际测试 我有一个从HTTPS通信中捕获的数据,由TLS_ECDHE_RSA_和_AES_256_CBC_SHA加密 若我理解正确,客户机在TLS握手过程中会创建一个主密钥,然后使用服务器的公钥对其进行加密并发送到服务器。然后将该主密钥(作为纯文本)用作加密正在进行的通信的对称密钥。这是正确的吗 如果是,如果我知道主密钥,如何解密数据 一开始我觉得很简单,所以我写了这个脚本 $masterKey = '8ef36f0eb2c10ea6142693374

我正在努力了解HTTPS的工作原理,并做一些实际测试

我有一个从HTTPS通信中捕获的数据,由TLS_ECDHE_RSA_和_AES_256_CBC_SHA加密

若我理解正确,客户机在TLS握手过程中会创建一个主密钥,然后使用服务器的公钥对其进行加密并发送到服务器。然后将该主密钥(作为纯文本)用作加密正在进行的通信的对称密钥。这是正确的吗

如果是,如果我知道主密钥,如何解密数据

一开始我觉得很简单,所以我写了这个脚本

$masterKey = '8ef36f0eb2c10ea6142693374f6c5c7ae65eee5f6bd45bd1990b08e6c144227382726496b795d62284bd8c6c0cadbbdb';

$someRandomEncryptedData = '170303001D314A69C7DF95E07AAF51FBDA01C178D45330BC902308DF8C418FA5B02B';

$sDecrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, pack('H*', $masterKey), pack('H*', $someRandomEncryptedData), MCRYPT_MODE_CBC);

echo $sDecrypted;
然后我注意到主密钥是96字节长(48作为二进制字符串),这导致PHP警告,因为密钥应该是256位(32字节)长。我错过什么了吗

客户端在请求过程中创建一个主密钥,然后使用服务器的公钥对其进行加密并发送到服务器。然后将该主密钥(作为纯文本)用作加密正在进行的通信的对称密钥。这是正确的吗

总而言之,不

因为您询问的是DH和ECDH,它们是密钥协商协议:客户机不会生成随机密钥,在服务器的公钥下对其进行加密,然后将其发送到服务器。这是密钥传输(如RSA密钥传输),而不是DH或ECDH。TLS 1.3中的关键传输正在消失

TLS分为两个阶段:密钥协议和批量传输。阶段的定义不如IPSec中的定义好。当客户端和服务器使用DH或ECDH时,它们会得到一个
premaster\u secret
。这就是Diffie-Hellman或椭圆曲线Diffie-Hellman的共享秘密

他们获取
premaster\u secret
,添加一个客户机随机数、一个服务器随机数,然后得到一个
master\u secret
。然后他们获取
主密钥
,并从中导出6个对称密钥:

  • 客户首字母IV
  • 客户端加密密钥
  • 客户端mac密钥
  • 服务器首字母IV
  • 服务器加密密钥
  • 服务器mac密钥
这些密钥用于为块密码或流密码设置密钥

如果您注意到,每一方都贡献了
premaster\u secret
——客户端贡献了
g^a
,服务器贡献了
g^b
。然后,每一方都通过nonce(客户端随机数和服务器随机数)为
主密钥

双方都有两种贡献的原因是传输方案,如RSA密钥传输,不允许服务器贡献
premaster\u secret
。服务器必须等待
master_secret
的派生,才能通过nonce提供密钥材料

因此,进程是从
premaster_secret
master_secret
到6个会话密钥。我不确定主钥匙在哪里


如果是,如果我知道主密钥,如何解密数据

我认为如果你有万能钥匙的话,把它插入Wireshark通常会更容易。Wireshark wiki讨论了主密钥(虽然我不知道它是什么-有
premaster\u secret
master\u secret
)。有关详细信息,请参阅Wireshark wiki


一开始我觉得很简单,所以我写了这个脚本

$masterKey = '8ef36f0eb2c10ea6142693374f6c5c7ae65eee5f6bd45bd1990b08e6c144227382726496b795d62284bd8c6c0cadbbdb';

$someRandomEncryptedData = '170303001D314A69C7DF95E07AAF51FBDA01C178D45330BC902308DF8C418FA5B02B';

$sDecrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, pack('H*', $masterKey), pack('H*', $someRandomEncryptedData), MCRYPT_MODE_CBC);

echo $sDecrypted;
是的……:)查看RFC5246。那是。那么让我们来谈谈easy:)


然后我注意到主密钥是96字节长(48作为二进制字符串)


96字节是伪随机函数(PRF)的输出。查看RFC 5246,第13页。

谢谢,我想不会那么容易。我只是在阅读一些文档,但它可能已经过时了,因为它使用了一些不同的密钥交换机制。这就是我困惑的地方。我想实现的是,只需读取原始数据包并了解所有需要知道的密钥,我就可以自己使用一些自制脚本从头开始解密文本。我只是想知道事情是如何在尽可能低的水平上运行的