StupidBeauty
Read times:2744Posted at: - no title specified

Qt5.4开发文档翻译:QSslSocket类,QSslSocket Class

QSslSocket 类,为客户端和服务器端提供了一个由 SSL加密 的套接字。 详细说明……

头文件:

#include <QSslSocket>

qmake指令

QT += network

自此版本开始引入:

Qt 4.3

继承

QTcpSocket .

注意: 这个类中的所有函数都是 可重入的

详细说明

QSslSocket 类,为客户端和服务器端提供了一个由 SSL加密 的套接字。

QSslSocket 建立 一个安全的、加密的 TCP连接 ,可用来传输加密数据。 在客户端和服务器端都可以使用,并且它支持现代的 SSL协议 ,包括 SSLv3 TLSv1_0 。默认情况 下, QSslSocket 会使用 TLSv1_0 ,但是,妳可以在开始握手之前调用 setProtocol ()来改变它所使用的SSL 协议。

当套接字进入 ConnectedState 状态之后, SSL加密功能 就以已有的TCP 流为基础开始工作。 有两种简单的方法可用来利用 QSslSocket 建立一个安全的连接:利用 一个从头开始进行的 SSL握手 ;或者,在连接以一种未加密的方式建立之后,再进行一次 SSL握手

最常见的使用 QSslSocket 的方法是,构建一个对象,然后调用 connectToHostEncrypted ()以启动一个安全连接。这个方法,会在连接建立之后立即启动一次 SSL握手

QSslSocket *socket = new QSslSocket (this);

connect (socket, SIGNAL(encrypted()), this, SLOT(ready()));

socket-> connectToHostEncrypted ("imap.example.com", 993);

与普通的 QTcpSocket 类似, QSslSocket 会依次进入 HostLookupState ConnectingState 状态 ,并且,连接成功的话,最终进入 ConnectedState 状态。然后 ,会自动开始进行握手,如果握手成功,则,会发射 encrypted ()信号,以表明,此套接字已经进入加密模式,可以使用了。

注意,调用 connectToHostEncrypted ()之后(也就是说,在 encrypted ()信号被发射之前)就可立即向套接字中写入数据。数据 会储存在 QSslSocket 的队列中,直到发射了 encrypted ()信号才开始发送。

在已有的连接上使用延迟 SSL握手 的一个例子是,某个 SSL服务器 对一个入站连接进行安全加密。假设,妳创建了一个 SSL服务器 类,它是 QTcpServer 的一个子类。 妳需要覆盖 QTcpServer::incomingConnection ()方法,改写 成类似于下面示例的代码,其中,会创建一个 QSslSocket 实例,然后调用 setSocketDescriptor ()以将新套接字的描述符替换成传入的已有的那个。然后 ,它会调用 startServerEncryption ()以发起SSL 握手。

void SslServer::incomingConnection(qintptr socketDescriptor)

{

QSslSocket *serverSocket = new QSslSocket ;

if (serverSocket->setSocketDescriptor(socketDescriptor)) {

connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));

serverSocket->startServerEncryption();

} else {

delete serverSocket;

}

}

如果 发生了错误,则, QSslSocket 会发射 sslErrors ()信号 在这种情况下,如果未采取行动来忽略这些错误,则,该连接会被断开。 要想让连接继续保持,而忽略错误事件的话,则,可以调用 ignoreSslErrors () ,调用的时机可以是在错误发生之后触发的信号槽中,也可以是在该 QSslSocket 构造之后尝试建立连接之前。 这将使得 QSslSocket 忽略 它在与对端进行认证的过程中的错误。当妳忽略SSL 握手过程中的错误的时候,应当保持警惕,因为,安全连接的一个基本要素就是,握手过程应当成功完成。

一旦加密完成,妳就可以像一个普通的 QTcpSocket 那样来使用 QSslSocket 了。 readyRead () 被发射的时候,妳就可以调用 read () canReadLine () readLine () getChar () 来从 QSslSocket 的内部缓冲区中读取被解密的数据, 也可以调用 write () putChar () 来将数据写回到对端节点。 QSslSocket 会自动将写入的数据进行加密,并且在数据被写入之后发射 encryptedBytesWritten ()信号。

作为 一个便利功能, QSslSocket 支持 QTcpSocket 的阻塞函数: waitForConnected () waitForReadyRead () waitForBytesWritten () waitForDisconnected () 它还提供了 waitForEncrypted () ,这个函数会阻塞住调用它的线程,直到加密连接建立成功为止。

QSslSocket socket;

socket. connectToHostEncrypted ("http.example.com", 443);

if (!socket.waitForEncrypted()) {

qDebug () << socket.errorString();

return false;

}

socket. write ("GET / HTTP/1.0\r\n\r\n");

while (socket.waitForReadyRead())

qDebug () << socket. readAll ().data();

QSslSocket 提供 了一组丰富的、易用的应用编程接口,用来管理:加密密钥、私钥和本地、对端、认证机构( Certification Authority (CA) )的证书。 它还提供了一个应用编程接口,用来处理握手阶段发生的错误。

还可以对以下功能进行自定义:

注意: 如果能够找到 的话,则,在Unix 系统中的根证书会从标准的证书目录中按需载入。如果 妳不希望对根证书进行按需载入,则,妳需要: 在程序中第一个SSL 握手发生之前调用静态函数 setDefaultCaCertificates ()(例如," QSslSocket::setDefaultCaCertificates ( QSslSocket::systemCaCertificates ());");或者,针对具体 QSslSocket 实例,在发生SSL 握手之前,调用 setCaCertificates ()。

欲知更多关于密钥 和证书的信息,则参考 QSslCipher QSslCertificate

注意: 请区分出 bytesWritten ()信号和 encryptedBytesWritten ()信号之间的区别。对于 QTcpSocket ,每当有数据被写入到该TCP 套接字中,就会发射 bytesWritten ()信号。对于 QSslSocket ,每当数据正在 被加密时会发射 bytesWritten ()信号,而当数据被写入到TCP 套接字时,会发射 encryptedBytesWritten ()信号。

参考 QSslCertificate QSslCipher QSslError

成员类型文档

enum QSslSocket::PeerVerifyMode

描述 QSslSocket 所使用的节点认证模式。默认模式 AutoVerifyPeer ,它会根据该套接字的QSocket::SslMode 来选择一种适当的模式。

常量

说明

QSslSocket::VerifyNone

0

QSslSocket 不会要求对方节点发送证书。如果妳对于对端节点的身份不感兴趣,那么,就可以设置这个模式。连接仍然是加密的,并且,妳的套接字仍然会根据对方的请求向对方节点发送自己的本地证书。

QSslSocket::QueryPeer

1

QSslSocket 会向对方节点请求获取一个证书,但是并不要求该证书是有效的。当妳想要向用户显示对方节点的证书,而又不想影响到实际的SSL握手过程的时候,这就狠有用了。这种模式,对于服务器来说是默认模式。

QSslSocket::VerifyPeer

2

QSslSocket 会在SSL 握手阶段向对方节点请求获取一个证书,并且,要求该证书是有效的。如果失败,则, QSslSocket 会发射 QSslSocket::sslErrors ()信号。这种模式,对于客户端来说是默认模式。

QSslSocket::AutoVerifyPeer

3

QSslSocket 会自动选择模式:对于服务器套接字,使用QueryPeer;对于客户端套接字,使用VerifyPeer

这个枚举值是自Qt 4.4 引入或修改的。

参考 QSslSocket::peerVerifyMode ()

enum QSslSocket::SslMode

描述对于 QSslSocket 可用 的连接模式。

常量

说明

QSslSocket::UnencryptedMode

0

此套接字未加密。它的行为与 QTcpSocket 等价。

QSslSocket::SslClientMode

1

这个套接字是一个客户端SSL套接字。它或者是处于已经加密的状态,或者是处于SSL握手阶段(参考 QSslSocket::isEncrypted ())

QSslSocket::SslServerMode

2

这个套接字是一个服务器端SSL套接字。它或者是处于已经加密的状态,或者是处于SSL握手阶段(参考 QSslSocket::isEncrypted ())

成员函数文档

void  QSslSocket:: addCaCertificate (const  QSslCertificate  &  certificate )

将证书 certificate加入到此套接字的CA证书数据库CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。

要想加入多个证书,则使用 addCaCertificates ()。

参考 caCertificates () setCaCertificates ()

bool  QSslSocket:: addCaCertificates (const  QString  &  path QSsl::EncodingFormat format  = QSsl::Pem, QRegExp::PatternSyntax syntax  = QRegExp::FixedString)

在路径 path 中搜索所有的文件,找到以特定格式 format 编码的证书,并且将它们加入到此套接字的CA 证书数据库中。 path 可以是显式指定的,也可以包含按照语法 syntax 来编写的通配符。如果 有一到多个证书被加入到此套接字的CA 证书数据库,则返回真( true );否则返回假( false )。

CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。

欲进行更精确的控制,则使用 addCaCertificate ()。

参考 addCaCertificate () QSslCertificate::fromPath ()

void  QSslSocket:: addCaCertificates (const  QList < QSslCertificate > &  certificates )

将证书 certificates加入到此套接字的CA证书数据库。CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。

欲进行更精确的控制,则使用 addCaCertificate ()。

参考 caCertificates () addDefaultCaCertificate ()

[static] void  QSslSocket:: addDefaultCaCertificate (const  QSslCertificate  &  certificate )

将证书 certificate加入到默认CA证书数据库中。每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库

参考 defaultCaCertificates () addCaCertificates ()

[static] bool  QSslSocket:: addDefaultCaCertificates (const  QString  &  path QSsl::EncodingFormat encoding  = QSsl::Pem, QRegExp::PatternSyntax syntax  = QRegExp::FixedString)

在路径 path 中搜索所有的文件,找到以特定格式 format 编码的证书,并且将它们加入到默认CA 证书数据库中。 path 可以是显式指定的,也可以包含按照语法 syntax 来编写的通配符。如果 有任何CA 证书被加入到默认数据库中,则返回真( true )。

每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库

参考 defaultCaCertificates () addCaCertificates () addDefaultCaCertificate ()

[static] void  QSslSocket:: addDefaultCaCertificates (const  QList < QSslCertificate > &  certificates )

将证书 certificates加入到默认CA证书数据库中。每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。

参考 defaultCaCertificates () addCaCertificates ()

QList < QSslCertificate > QSslSocket:: caCertificates () const

返回 此套接字的 CA证书数据库 CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。 可在握手之前利用 addCaCertificate ()、 addCaCertificates ()和 setCaCertificates ()来修改它。

注意: Unix中,如果根证书是按需载入的,则,此方法可能返回一个空列表。

参考 addCaCertificate () addCaCertificates () setCaCertificates ()

[static] QList < QSslCertificate > QSslSocket:: defaultCaCertificates ()

返回当前 的默认 CA证书数据库 这个数据库,最初会被设置为妳的系统中的默认 CA证书数据库 。如果 未找到系统的默认数据库,则,会返回一个空数据库。 妳可以调用 setDefaultCaCertificates (),以使用妳自己的CA 证书数据库来覆盖默认的CA 证书数据库。

每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。

注意: Unix中,如果根证书是按需载入的,则,此方法可能返回一个空列表。

参考 setDefaultCaCertificates () caCertificates ()

[slot] void  QSslSocket:: ignoreSslErrors ()

这个信号槽,会告诉 QSslSocket ,忽略 QSslSocket 的握手阶段的错误,继续建立连接。如果 妳想要在握手阶段出错的情况下来继续连接动作的话,则,妳必须调用此信号槽,可以在连接到 sslErrors ()的某个信号槽中调用它,也可以在握手阶段之前调用它。如果 妳没有在出错时或握手之前调用它,则,在发射了 sslErrors ()信号之后,连接会被断开。

如果 SSL握手阶段 中没有发生错误 ( 也就是说,正确 地验证了对方节点的身份 ) ,则, QSslSocket 不会发射 sslErrors ()信号,因此 就没有必要调用此函数了。

警告: 请注意,每次都应当让用户调查一下由 sslErrors ()信号所报告的错误,并且只有 在用户确认可以继续的情况下才调用这个方法。如果 发生了未预期的错误,则,连接应当被断开。如果 不让用户调查实际的错误就直接调用此方法,那么,会暴露出妳的应用程序中的一个安全隐患。请小心使用!

参考 sslErrors ()

void  QSslSocket:: ignoreSslErrors (const  QList < QSslError > &  errors )

这是一个重载函数。

这个方法,告诉 QSslSocket 要仅仅忽略掉由 errors 所指定的那些错误。

注意:因为大部分SSL错误都与证书相关联,所以,对于其中的大部分,妳必须设置这个SSL 错误所预期的相关证书。举个例子,如果妳想连接到一个使用自签名证书的服务器,那么,可考虑使用以下代码:

QList < QSslCertificate > cert = QSslCertificate ::fromPath(QLatin1String("server-certificate.pem"));

QSslError error ( QSslError ::SelfSignedCertificate, cert.at(0));

QList < QSslError > expectedSslErrors;

expectedSslErrors.append(error);

QSslSocket socket;

socket. ignoreSslErrors (expectedSslErrors);

socket. connectToHostEncrypted ("server.tld", 443);

如果多次调用这个函数,则会替换掉在之前调用过程中设置的错误列表。妳可以在调用此函数的时候传入一个空列表,这样就能够清除掉要忽略的错误列表了。

此函数是从Qt 4.6 开始引入的。

参考 sslErrors ()

QSslCertificate  QSslSocket:: localCertificate () const

返回 此套接字的本地 证书 ,或者,如果未设置本地证书,则返回一个空白的证书。

参考 setLocalCertificate () privateKey ()

QList < QSslCertificate > QSslSocket:: localCertificateChain () const

返回 此套接字的本地 证书 链,或者,如果未设置本地证书,则返回一个空列表。

此函数是从Qt 5.1 开始引入的。

参考 setLocalCertificateChain ()

QSslCertificate  QSslSocket:: peerCertificate () const

返回对方节点的数字证书(也就是说,妳所连接的主机的证书),或者,如果该节点未设置证书,则返回一个空证书。

对方证书,会在握手阶段自动验证,因此,这个函数,一般是用来获取对方证书并用于显示,或者用于进行连接诊断。它包含着关于对方节点的信息,包括它的主机名、证书发布者和对方节点的公钥。

因为对方节点 的证书是在握手阶段就设置了的,所以,可以安全地在连接到 sslErrors ()信号或 encrypted ()信号的某个信号槽中访问到对方节点的证书。

如果返回了一个空证书,则,可能意味着SSL握手失败,或者可能意味着妳所连接的那个主机没有证书,或者可能意味着根本没有连接。

如果 妳想检查对方节点的完整证书链,则,使用 peerCertificateChain ()来一次性获取它们。

参考 peerCertificateChain ()

QList < QSslCertificate > QSslSocket:: peerCertificateChain () const

返回对方节点的数字证书链,或者返回一个空的证书列表。

对方节点的证书是在握手阶段就自动检查的。这个函数一般是用来获取证书以进行显示的,或者进行连接诊断的。它包含着关于对方节点和证书发布者的信息,包括它的主机名、证书发布者名字和证书发布者的公钥。

因为对方节点 的证书是在握手阶段就 QSslSocket 设置了的,所以,可以安全地在连接到 sslErrors ()信号或 encrypted ()信号的某个信号槽中访问到对方节点的证书。

如果返回了一个空列表,则,可能意味着SSL握手失败,或者可能意味着妳所连接的那个主机没有证书,或者可能意味着根本没有连接。

如果 妳只想获取到对方节点的直接证书,则使用 peerCertificate ()。

参考 peerCertificate ()

[signal] void  QSslSocket:: peerVerifyError (const  QSslError  &  error )

QSslSocket 可能 会在 SSL 握手阶段成功建立加密连接之前多次发射这个信号, 以表明在验证对方节点的身份时出现了错误。错误 error 通常 是一个提示,表明 QSslSocket 无法安全 地验证对方节点的身份。

这个信号的作用是,在某些事情出错的情况下提早知会妳。连接到这个信号之后,妳就可以在握手完毕之前,在所连接到的信号槽中手动断开连接。如果妳未采取行动,则, QSslSocket 会进一步发射 QSslSocket::sslErrors ()信号。

此函数是从Qt 4.4 开始引入的。

参考 sslErrors ()

QSslKey  QSslSocket:: privateKey () const

返回此套接字的私钥。

参考 setPrivateKey () localCertificate ()

void  QSslSocket:: setCaCertificates (const  QList < QSslCertificate > &  certificates )

将此套接字的CA证书数据库设置 certificates 。必须在 SSL 握手之前设置证书数据库。CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。

可以调用此函数,并且传入由 defaultCaCertificates ()返回的CA 证书列表,这样就能够将CA 证书数据库重置为当前的默认CA 证书数据库了。

参考 caCertificates () defaultCaCertificates ()

[static] void  QSslSocket:: setDefaultCaCertificates (const  QList < QSslCertificate > &  certificates )

将默认的CA证书数据库设置 certificates 。默认CA 数据库,最初会被设置为妳的系统中的默认CA证书数据库。妳可以利用这个函数来用自己的CA 证书数据库覆盖掉默认CA 证书数据库。

每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。

参考 defaultCaCertificates () addDefaultCaCertificate ()

void  QSslSocket:: setLocalCertificate (const  QSslCertificate  &  certificate )

将此套接字的本地证书设置为 certificate 。如果妳要向对方节点确认妳的身份,那么,本地证书是必要的。它是与私钥一起使用的;如果妳设置了本地证书,那么,妳还必须设置私钥。

对于服务器套接字来说,本地证书和私钥是必要的,但是,偶尔的情况下,服务器要求客户端进行认证,此时,客户端套接字也是需要它们的。

参考 localCertificate () setPrivateKey ()

void  QSslSocket:: setLocalCertificate (const  QString  &  path QSsl::EncodingFormat format  = QSsl::Pem)

这是一个重载函数。

将此套接字的本地 证书 设置 为在路径 path 处找到的第一个证书, 其解析过程是按照格式 format 来进行的。

void  QSslSocket:: setLocalCertificateChain (const  QList < QSslCertificate > &  localChain )

将SSL 握手阶段要呈交给对方节点的证书链设置为 localChain

此函数是从Qt 5.1 开始引入的。

参考 localCertificateChain () QSslConfiguration::setLocalCertificateChain ()

void  QSslSocket:: setPrivateKey (const  QSslKey  &  key )

将此套接字的私有 密钥 设置 key 。对于 要向对方SSL 节点证明自己身份的客户端和服务器来说,私有密钥和本地 证书 是必需的。

如果妳是在创建一个SSL 服务器套接字的话,私钥和本地证书都是必需的。如果妳是在创建一个SSL客户端套接字,并且需要向SSL 服务器表明自己的身份的话,则,私钥和本地证书也是必需的。

参考 privateKey () setLocalCertificate ()

void  QSslSocket:: setPrivateKey (const  QString  &  fileName QSsl::KeyAlgorithm algorithm  = QSsl::Rsa, QSsl::EncodingFormat format  = QSsl::Pem, const  QByteArray  &  passPhrase  = QByteArray())

这是一个重载函数。

读取文件 fileName 中的字符串,使用指定的算法 algorithm 和编码格式 format 进行解码,以构造一个 SSL密钥 。如果 所编码的密钥是加密过的,则,会使用 passPhrase 来解密。

会将此套接字的私钥设置为此过程所构造出来的密钥。那些 要向对方SSL 节点证明自己身份的客户端和服务器,会用上私钥和本地 证书

如果妳是在创建一个SSL 服务器套接字的话,私钥和本地证书都是必需的。如果妳是在创建一个SSL客户端套接字,并且需要向SSL 服务器表明自己的身份的话,则,私钥和本地证书也是必需的。

参考 privateKey () setLocalCertificate ()

void  QSslSocket:: setSslConfiguration (const  QSslConfiguration  &  configuration )

将此套接字的SSL配置选项设置 configuration 的内容。这个函数,会将本地证书、加密算法、私钥和CA证书集设置成 configuration 中所存储的那些东西。

无法设置那些与SSL 状态相关的字段。

此函数是从Qt 4.4 开始引入的。

参考 sslConfiguration () setLocalCertificate () setPrivateKey () setCaCertificates () setCiphers ()

QSslConfiguration  QSslSocket:: sslConfiguration () const

返回此套接字的SSL配置状态。一个套接字的默认SSL配置选项,就是,使用默认加密算法、默认CA证书集、无本地私钥、无本地证书。

SSL配置选项中还包含一些会随着时间改变且不会发出通知的字段。

此函数是从Qt 4.4 开始引入的。

参考 setSslConfiguration () localCertificate () peerCertificate () peerCertificateChain () sessionCipher () privateKey () ciphers () caCertificates ()

QList < QSslError > QSslSocket:: sslErrors () const

返回最后 发生的那些SSL 错误的列表。 这个列表与 QSslSocket 通过sslErrors()信号传递的列表相同。如果 在建立加密连接的过程中未发生错误,则,此函数会返回一个空列表。

参考 connectToHostEncrypted ()

[signal] void  QSslSocket:: sslErrors (const  QList < QSslError > &  errors )

QSslSocket 会在 SSL握手阶段之后 发射这个信号,以表明在验证对方节点的身份时发生了一个或多个错误。 这些错误通常是一种提示,以表明 QSslSocket 无法安全 地验证对方节点的身份。除非 妳采取了措施,否则,在发射了此信号之后,连接会被断开。

如果 妳希望在发生错误的情况下仍然继续建立连接,那么,必须在连接到这个信号的某个信号槽中调用 QSslSocket::ignoreSslErrors ()。如果 妳想在日后访问这个错误信息列表,则,可以调用 sslErrors () ( 不带参数 )

errors 中包含了一或多个错误,它们使得 QSslSocket 无法验证对方节点 的身份。

注意: 在连接到这个信号时不能使用 Qt::QueuedConnection ,否则,调用 QSslSocket::ignoreSslErrors ()将没有效果。

参考 peerVerifyError ()

[static] QList < QSslCertificate > QSslSocket:: systemCaCertificates ()

这个函数能够获取到由操作系统提供的 CA证书数据库 这个函数所返回的 CA证书数据库 ,会被用来初始化 defaultCaCertificates ()所返回的数据库。 妳可以调用 setDefaultCaCertificates (),以便使用妳自己的数据库来替换它。

参考 caCertificates () defaultCaCertificates () setDefaultCaCertificates ()

Ольга Куриленко

熙来

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands