我有一个php ssl客户端和一个C ++ Qt ssl服务器,我需要对客户端进行身份验证而不是对服务器进行身份验证。

原因是C ++ Qt ssl服务器实际上在桌面应用程序上运行,出于安​​全原因,我也不想为桌面应用程序提供私钥,也因为服务器不需要自行对其进行身份验证。

因此,我为客户端提供了证书和私钥,而服务器仅具有对客户端进行身份验证的证书。

但是,在上述情况下,我从服务器端收到了ssl错误,由于缺少共享密码,握手失败。

如果我为服务器提供其自己的本地私钥和证书,则握手成功完成。

下面一些PHP代码来设置SSL:

/* $local_cert_path is a file containing a complete certificate
 * verification chain and the private key
 */
if (! is_file($local_cert_path))
{
    throw new Exception(sprintf('cannot find certificate path: %s', $local_cert_path));
}
$this->ctx = stream_context_create();
stream_context_set_option($this->ctx, 'ssl', 'verify_peer', FALSE);
stream_context_set_option($this->ctx, 'ssl', 'allow_self_signed', TRUE);
stream_context_set_option($this->ctx, 'ssl', 'local_cert', $local_cert_path);


和C ++(Qt):

QList<QSslCertificate> certs = cacerts();
socket->setCaCertificates(certs); // loading the CA
// socket->setLocalCertificate(":/res/cert.pem", QSsl::Pem);
// socket->setPrivateKey(":/res/key.pem");
socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
socket->setProtocol(QSsl::TlsV1);


如果我为服务器提供了自己的本地私钥和证书(取消了以上两行的注释),则握手有效。

最佳答案

为了防止MITM攻击,必须验证SSL / TLS服务器的身份。即使您使用客户端证书身份验证(也称为相互身份验证),客户端也需要检查服务器的身份(通常通过检查服务器是否信任其X.509证书以及它是否与证书中的预期服务器身份相匹配)。为此,TLS服务器需要配置有这样的证书(及其关联的私钥)。
没有这个,客户端就可以很好地使用客户端证书进行身份验证,只是它不知道对其进行身份验证(从而可能导致MITM攻击)。

话虽如此,在您的情况下,TLS服务器不必是TCP服务器。确实,TLS倾向于在TCP之上使用。在大多数情况下,TCP客户端也是TLS客户端,并且一旦客户端建立了TCP连接,它还将在其上发送TLS ClientHello,从而开始其作为TLS客户端的角色。

通过使服务器启动发送ClientHello的TLS握手,您可能能够使TCP服务器充当TLS服务器。实际上,TLS Glossary将客户端定义为:


  启动与TLS连接的应用程序实体
        服务器。这可能暗示也可能不暗示客户发起了
        基础传输连接。主要业务
        服务器和客户端之间的区别在于服务器是
        通常经过身份验证,而客户端仅是可选的
        已验证。


我已经在Java中尝试过,并且效果很好。在Java中,仅在握手发生后才固定角色是客户端,而服务器是固定的。在此之前,您仍然可以使用setUseClientMode更改SSLSocket的角色,尽管SSLServerSocket(从SSLServerSocketFactory获取的将处于服务器模式,而SSLSocket是从普通的Socket转换的(结果可以用作服务器端TLS套接字,反之亦然。

TLS允许这样做,但是我不知道您使用的框架是否可行。

对于通过accept (available in SMTP, IMAP and LDAP, for example)之类的机制升级套接字的协议,通常将普通的TCP套接字转换为TLS套接字。

您需要建立从“真实”客户端到“真实”服务器的纯TCP连接,将TCP客户端套接字转换为TLS套接字并将其设置为服务器模式,将TCP服务器套接字转换为TLS套接字,对其进行设置在客户端模式下启动握手。

关于php - 在SSL握手中,角色是否可以互换?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8234033/

10-15 13:17