php 中的 TLS 会话恢复

TLS Session Resumption in php

我正在编写一个多线程 php 客户端,它向 apache 反向代理发出 https 请求并测量一些统计数据。我正在写一篇关于使用 TLS 会话恢复提高性能的学士论文。现在我需要做一个概念证明 proves/disproves 这个。目前我有这段代码:

            $this->synchronized(function($this){
                $this->before = microtime(true);
            }, $this);

            $url = 'https://192.168.0.171/';
            # Some dummy data
            $data = array('name' => 'Nicolas', 'bank account' => '123462343');

            // use key 'http' even if you send the request to https://...
            $options = array(
                'http' => array(
                    'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                    'method' => 'POST',
                    'content' => http_build_query($data)
                ),
                "ssl" => array(
                    "verify_peer" => false,
                    "verify_peer_name" => false,
                    "ciphers" => "HIGH:!SSLv2:!SSLv3"
                )
            );

            $context = stream_context_create($options);
            $result = file_get_contents($url, false, $context);
            $this->synchronized(function($this){
                $this->after = microtime(true);
            }, $this);

            $this->counter_group->write($this->before, $this->after, $result); 

此代码可以进行完整的握手,但我似乎无法弄清楚如何在 php?

中恢复握手

如有任何帮助,我们将不胜感激!

您可以尝试 PHP curl 并使用 CURL_LOCK_DATA_SSL_SESSION

来自 PHP 文档 http://php.net/manual/en/function.curl-share-setopt.php

CURL_LOCK_DATA_SSL_SESSION Shares SSL session IDs, reducing the time spent on the SSL handshake when reconnecting to the same server. Note that SSL session IDs are reused within the same handle by default

正如您从上面的描述中所读到的,session id 被同一个句柄重复使用。但是如果你想在句柄之间共享,你可以使用 curl_share_init 例如

$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);

然后你可以在不同的请求之间重复使用$sh

$ch1 = curl_init('https://192.168.0.171');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_setopt($ch1, CURLOPT_SSLVERSION, 6); // TLSV1.2
curl_setopt($ch1, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');

curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, 
http_build_query( array('name' => 'Nicolas', 'bank account' => '123462343') ));
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);

$output = curl_exec($ch1);

然后重用(恢复握手)

$ch2 = curl_init('https://192.168.0.171');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_setopt($ch2, CURLOPT_SSLVERSION, 6); // TLSV1.2
curl_setopt($ch2, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// ( ... )
curl_exec($ch2);

并关闭连接

curl_close($ch1);
curl_close($ch2);

但您还需要玩 CURLOPT_SSLVERSION 和 CURLOPT_SSL_CIPHER_LIST 。另外,我认为你应该切换到不同的语言,因为 PHP 有它自己的怪癖,如果你证明或反驳论文,最好使用更接近裸机的东西,这样你就可以确定额外的层(PHP) 不会破坏您的基准。我确实测量了两个请求的性能,这有点违反直觉,但第二个请求几乎慢了两倍。