客户端应用程序如何使用Qt中的自签名证书连接到SSL服务器?
我想用ssl与POP3服务器通信,用我的客户端应用程序与端口995通信 服务器的证书是自签名的,运行应用程序时收到的错误是: 证书是自签名的,不受信任 代码的一部分是:客户端应用程序如何使用Qt中的自签名证书连接到SSL服务器?,qt,ssl,certificate,self-signed,Qt,Ssl,Certificate,Self Signed,我想用ssl与POP3服务器通信,用我的客户端应用程序与端口995通信 服务器的证书是自签名的,运行应用程序时收到的错误是: 证书是自签名的,不受信任 代码的一部分是: socket = new QSslSocket(this); QFile certfile("D:\\hani\\cert\\localhost.localdomain.pem"); Q_ASSERT(certfile.open(QIODevice::ReadOnly)); QList<QSslCertificate>
socket = new QSslSocket(this);
QFile certfile("D:\\hani\\cert\\localhost.localdomain.pem");
Q_ASSERT(certfile.open(QIODevice::ReadOnly));
QList<QSslCertificate> certList;
QSslCertificate cert(&certfile,QSsl::Pem);
certList.append(cert);
socket->addCaCertificate(cert);
socket->setCaCertificates(certList);
QList<QSslCertificate> serverCert = socket->caCertificates();
socket=新的QSslSocket(此);
QFile证书文件(“D:\\hani\\cert\\localhost.localdomain.pem”);
Q_断言(certfile.open(QIODevice::ReadOnly));
QList证书列表;
QSsl证书(证书文件(&certfile,QSsl::Pem);
certList.append(cert);
套接字->添加证书(证书);
套接字->设置证书(证书列表);
QList serverCert=socket->caCertificates();
我能做什么?
查看qsslssocket::sslErrors
的描述:
If you want to continue connecting despite the errors that have occurred,
you must call QSslSocket::ignoreSslErrors() from inside a slot connected
to this signal.
免责声明:这是非常不明智的,因为它让服务器“完全开放”给不要调用
忽略错误()
。它完全违背了SSL/TLS的目的。在一些非常特殊的情况下,可以安全地调用它,但这种(自签名证书)并不是特例
下面即将运行的代码演示了如何安全地接受服务器自签名证书。不要抄近路
司机:
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
QTextStream log(stdout);
DummyClient dummy(log);
QObject::connect(&dummy, SIGNAL(done()), &app, SLOT(quit()));
return app.exec();
}
DummyClient
类:
/*
* Show how to safely authenticate a TLS server which uses a self-signed certificate.
* Warning: No error handling to keep the code short.
*/
class DummyClient : public QObject {
Q_OBJECT
public:
DummyClient(QTextStream& log)
: _log(log),
_sock(new QSslSocket(this)) {
connect(_sock, SIGNAL(encrypted()), this, SLOT(onEncrypted()));
connect(_sock, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(onSslErrors(QList<QSslError>)));
connect(_sock, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(onErrors(QAbstractSocket::SocketError)));
// Trust store: which CAs or self-signed certs we are going to trust.
//
// We use setCaCertificates() instead than QSslSocket::addCaCertificates()
// because we don't want to trust the ~200 default CAs.
QList<QSslCertificate> trustedCas = QSslCertificate::fromPath("server-cert.pem");
if (trustedCas.empty()) {
qFatal("Error: no trusted Cas");
}
_sock->setCaCertificates(trustedCas);
bool mutualAuth = false;
if (mutualAuth) {
// Our identity
_sock->setPrivateKey("client-key.pem");
_sock->setLocalCertificate("client-cert.pem");
}
_log << "Connecting" << endl;
// Note: serverName must match the cert CN or alternative name.
Qstring serverName = "myserver.example.org";
_sock->connectToHostEncrypted(serverName, 995);
}
signals:
void done();
private slots:
void onEncrypted() {
_log << "onEncrypted" << endl;
/* Everything is good. Start communicating. */
emit done();
}
void onSslErrors(QList<QSslError> errors) {
QSslError first = errors.takeFirst();
_log << "onSslErrors: " << first.errorString() << endl;
/* Something went wrong in the TLS handshake. Inform the user and quit! */
emit done();
}
void onErrors(QAbstractSocket::SocketError) {
_log << "onErrors: " << _sock->errorString() << endl;
emit done();
}
private:
QTextStream& _log;
QSslSocket* _sock;
};
/*
*演示如何安全地验证使用自签名证书的TLS服务器。
*警告:无错误处理以保持代码简短。
*/
类DummyClient:公共QObject{
Q_对象
公众:
DummyClient(QTextStream和日志)
:_log(log),
_袜子(新QSslSocket(本)){
连接(_sock,SIGNAL(encrypted()),this,SLOT(onEncrypted());
连接(_sock,信号(sslErrors(QList)),
这个插槽(onsserrors(QList));
连接(_sock,信号(错误(QAbstractSocket::socketterror)),
这个插槽(onerror(QAbstractSocket::socketterror));
//信任存储:我们将信任哪些CA或自签名证书。
//
//我们使用setCaCertificates()而不是QSslSocket::addCaCertificates()
//因为我们不想信任~200个默认CA。
QList trustedCas=QSslCertificate::fromPath(“server-cert.pem”);
if(trustedCas.empty()){
qFatal(“错误:无可信CA”);
}
_sock->setCaCertificates(受信任的CA);
bool mutualAuth=false;
如果(相互作用){
//我们的身份
_sock->setPrivateKey(“client key.pem”);
_sock->setLocalCertificate(“client-cert.pem”);
}
_日志不遵循此答案(调用ignoreSslErrors)。其效果是客户端将不再对服务器进行身份验证。任何类型的攻击都是可能的,包括中间人。请参阅我的答案。最后,这是一个很好的示例,说明了如何在不忽略ssl错误的情况下正确执行此操作。谢谢。但出于某种原因,QWebsocketServer不接受客户端的证书,尽管它已添加到st或者使用configuration.setCaCertificates(clientPemCertificate)
。您有这样的例子吗?或者其他解决方案吗?