Qt5.4开发文档翻译:QSslSocket类,QSslSocket Class
QSslSocket 类,为客户端和服务器端提供了一个由 SSL加密 的套接字。 详细说明……
头文件: |
#include <QSslSocket> |
qmake指令: |
QT += network |
自此版本开始引入: |
Qt 4.3 |
继承: |
注意: 这个类中的所有函数都是 可重入的 。
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) )的证书。 它还提供了一个应用编程接口,用来处理握手阶段发生的错误。
还可以对以下功能进行自定义:
•. 在握手阶段之前,可使用 setCiphers ()和 setDefaultCiphers ()来设置该套接字的加密密钥。
•. 在握手阶段之前,可使用 setLocalCertificate ()和 setPrivateKey ()来设置该套接字的本地证书和私钥。
•. CA证书数据库 ,可使用以下函数来扩展及自定义: addCaCertificate () 、 addCaCertificates () 、 setCaCertificates () 、 addDefaultCaCertificate () 、 addDefaultCaCertificates () 和 setDefaultCaCertificates () 。
注意: 如果能够找到 的话,则,在Unix 系统中的根证书会从标准的证书目录中按需载入。如果 妳不希望对根证书进行按需载入,则,妳需要: 在程序中第一个SSL 握手发生之前调用静态函数 setDefaultCaCertificates ()(例如," QSslSocket::setDefaultCaCertificates ( QSslSocket::systemCaCertificates ());");或者,针对具体 的 QSslSocket 实例,在发生SSL 握手之前,调用 setCaCertificates ()。
欲知更多关于密钥 和证书的信息,则参考 QSslCipher 和 QSslCertificate 。
注意: 请区分出 bytesWritten ()信号和 encryptedBytesWritten ()信号之间的区别。对于 QTcpSocket ,每当有数据被写入到该TCP 套接字中,就会发射 bytesWritten ()信号。对于 QSslSocket ,每当数据正在 被加密时会发射 bytesWritten ()信号,而当数据被写入到TCP 套接字时,会发射 encryptedBytesWritten ()信号。
参考 QSslCertificate 、 QSslCipher 和 QSslError 。
描述 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 () 。
描述对于 QSslSocket 可用 的连接模式。
常量 |
值 |
说明 |
QSslSocket::UnencryptedMode |
0 |
此套接字未加密。它的行为与 QTcpSocket 等价。 |
QSslSocket::SslClientMode |
1 |
这个套接字是一个客户端SSL套接字。它或者是处于已经加密的状态,或者是处于SSL握手阶段(参考 QSslSocket::isEncrypted ())。 |
QSslSocket::SslServerMode |
2 |
这个套接字是一个服务器端SSL套接字。它或者是处于已经加密的状态,或者是处于SSL握手阶段(参考 QSslSocket::isEncrypted ())。 |
将证书 certificate加入到此套接字的CA证书数据库。CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。
要想加入多个证书,则使用 addCaCertificates ()。
参考 caCertificates () 和 setCaCertificates () 。
在路径 path 中搜索所有的文件,找到以特定格式 format 编码的证书,并且将它们加入到此套接字的CA 证书数据库中。 path 可以是显式指定的,也可以包含按照语法 syntax 来编写的通配符。如果 有一到多个证书被加入到此套接字的CA 证书数据库,则返回真( true );否则返回假( false )。
CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。
欲进行更精确的控制,则使用 addCaCertificate ()。
参考 addCaCertificate () 和 QSslCertificate::fromPath () 。
将证书 certificates加入到此套接字的CA证书数据库。CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。
欲进行更精确的控制,则使用 addCaCertificate ()。
参考 caCertificates () 和 addDefaultCaCertificate () 。
将证书 certificate加入到默认CA证书数据库中。每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。
参考 defaultCaCertificates () 和 addCaCertificates () 。
在路径 path 中搜索所有的文件,找到以特定格式 format 编码的证书,并且将它们加入到默认CA 证书数据库中。 path 可以是显式指定的,也可以包含按照语法 syntax 来编写的通配符。如果 有任何CA 证书被加入到默认数据库中,则返回真( true )。
每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。
参考 defaultCaCertificates () 、 addCaCertificates () 和 addDefaultCaCertificate () 。
将证书 certificates加入到默认CA证书数据库中。每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。
参考 defaultCaCertificates () 和 addCaCertificates () 。
返回 此套接字的 CA证书数据库 。 CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。 可在握手之前利用 addCaCertificate ()、 addCaCertificates ()和 setCaCertificates ()来修改它。
注意: 在Unix中,如果根证书是按需载入的,则,此方法可能返回一个空列表。
参考 addCaCertificate () 、 addCaCertificates () 和 setCaCertificates () 。
返回当前 的默认 CA证书数据库 。 这个数据库,最初会被设置为妳的系统中的默认 CA证书数据库 。如果 未找到系统的默认数据库,则,会返回一个空数据库。 妳可以调用 setDefaultCaCertificates (),以使用妳自己的CA 证书数据库来覆盖默认的CA 证书数据库。
每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。
注意: 在Unix中,如果根证书是按需载入的,则,此方法可能返回一个空列表。
参考 setDefaultCaCertificates () 和 caCertificates () 。
这个信号槽,会告诉 QSslSocket ,忽略 QSslSocket 的握手阶段的错误,继续建立连接。如果 妳想要在握手阶段出错的情况下来继续连接动作的话,则,妳必须调用此信号槽,可以在连接到 sslErrors ()的某个信号槽中调用它,也可以在握手阶段之前调用它。如果 妳没有在出错时或握手之前调用它,则,在发射了 sslErrors ()信号之后,连接会被断开。
如果 在 SSL握手阶段 中没有发生错误 ( 也就是说,正确 地验证了对方节点的身份 ) ,则, QSslSocket 不会发射 sslErrors ()信号,因此 就没有必要调用此函数了。
警告: 请注意,每次都应当让用户调查一下由 sslErrors ()信号所报告的错误,并且只有 在用户确认可以继续的情况下才调用这个方法。如果 发生了未预期的错误,则,连接应当被断开。如果 不让用户调查实际的错误就直接调用此方法,那么,会暴露出妳的应用程序中的一个安全隐患。请小心使用!
参考 sslErrors () 。
这是一个重载函数。
这个方法,告诉 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 () 。
返回 此套接字的本地 证书 ,或者,如果未设置本地证书,则返回一个空白的证书。
参考 setLocalCertificate () 和 privateKey () 。
返回 此套接字的本地 证书 链,或者,如果未设置本地证书,则返回一个空列表。
此函数是从Qt 5.1 开始引入的。
参考 setLocalCertificateChain () 。
返回对方节点的数字证书(也就是说,妳所连接的主机的证书),或者,如果该节点未设置证书,则返回一个空证书。
对方证书,会在握手阶段自动验证,因此,这个函数,一般是用来获取对方证书并用于显示,或者用于进行连接诊断。它包含着关于对方节点的信息,包括它的主机名、证书发布者和对方节点的公钥。
因为对方节点 的证书是在握手阶段就设置了的,所以,可以安全地在连接到 sslErrors ()信号或 encrypted ()信号的某个信号槽中访问到对方节点的证书。
如果返回了一个空证书,则,可能意味着SSL握手失败,或者可能意味着妳所连接的那个主机没有证书,或者可能意味着根本没有连接。
如果 妳想检查对方节点的完整证书链,则,使用 peerCertificateChain ()来一次性获取它们。
参考 peerCertificateChain () 。
返回对方节点的数字证书链,或者返回一个空的证书列表。
对方节点的证书是在握手阶段就自动检查的。这个函数一般是用来获取证书以进行显示的,或者进行连接诊断的。它包含着关于对方节点和证书发布者的信息,包括它的主机名、证书发布者名字和证书发布者的公钥。
因为对方节点 的证书是在握手阶段就 由 QSslSocket 设置了的,所以,可以安全地在连接到 sslErrors ()信号或 encrypted ()信号的某个信号槽中访问到对方节点的证书。
如果返回了一个空列表,则,可能意味着SSL握手失败,或者可能意味着妳所连接的那个主机没有证书,或者可能意味着根本没有连接。
如果 妳只想获取到对方节点的直接证书,则使用 peerCertificate ()。
参考 peerCertificate () 。
QSslSocket 可能 会在 SSL 握手阶段成功建立加密连接之前多次发射这个信号, 以表明在验证对方节点的身份时出现了错误。错误 error 通常 是一个提示,表明 QSslSocket 无法安全 地验证对方节点的身份。
这个信号的作用是,在某些事情出错的情况下提早知会妳。连接到这个信号之后,妳就可以在握手完毕之前,在所连接到的信号槽中手动断开连接。如果妳未采取行动,则, QSslSocket 会进一步发射 QSslSocket::sslErrors ()信号。
此函数是从Qt 4.4 开始引入的。
参考 sslErrors () 。
返回此套接字的私钥。
参考 setPrivateKey () 和 localCertificate () 。
将此套接字的CA证书数据库设置为 certificates 。必须在 SSL 握手之前设置证书数据库。CA证书数据库会被此套接字用于在握手阶段验证对方节点的证书。
可以调用此函数,并且传入由 defaultCaCertificates ()返回的CA 证书列表,这样就能够将CA 证书数据库重置为当前的默认CA 证书数据库了。
参考 caCertificates () 和 defaultCaCertificates () 。
将默认的CA证书数据库设置为 certificates 。默认CA 数据库,最初会被设置为妳的系统中的默认CA证书数据库。妳可以利用这个函数来用自己的CA 证书数据库覆盖掉默认CA 证书数据库。
每个SSL套接字的CA证书数据库都会被初始化为默认CA证书数据库。
参考 defaultCaCertificates () 和 addDefaultCaCertificate () 。
将此套接字的本地证书设置为 certificate 。如果妳要向对方节点确认妳的身份,那么,本地证书是必要的。它是与私钥一起使用的;如果妳设置了本地证书,那么,妳还必须设置私钥。
对于服务器套接字来说,本地证书和私钥是必要的,但是,偶尔的情况下,服务器要求客户端进行认证,此时,客户端套接字也是需要它们的。
参考 localCertificate () 和 setPrivateKey () 。
这是一个重载函数。
将此套接字的本地 证书 设置 为在路径 path 处找到的第一个证书, 其解析过程是按照格式 format 来进行的。
将SSL 握手阶段要呈交给对方节点的证书链设置为 localChain 。
此函数是从Qt 5.1 开始引入的。
参考 localCertificateChain () 和 QSslConfiguration::setLocalCertificateChain () 。
将此套接字的私有 密钥 设置 为 key 。对于 要向对方SSL 节点证明自己身份的客户端和服务器来说,私有密钥和本地 证书 是必需的。
如果妳是在创建一个SSL 服务器套接字的话,私钥和本地证书都是必需的。如果妳是在创建一个SSL客户端套接字,并且需要向SSL 服务器表明自己的身份的话,则,私钥和本地证书也是必需的。
参考 privateKey () 和 setLocalCertificate () 。
这是一个重载函数。
读取文件 fileName 中的字符串,使用指定的算法 algorithm 和编码格式 format 进行解码,以构造一个 SSL密钥 。如果 所编码的密钥是加密过的,则,会使用 passPhrase 来解密。
会将此套接字的私钥设置为此过程所构造出来的密钥。那些 要向对方SSL 节点证明自己身份的客户端和服务器,会用上私钥和本地 证书 。
如果妳是在创建一个SSL 服务器套接字的话,私钥和本地证书都是必需的。如果妳是在创建一个SSL客户端套接字,并且需要向SSL 服务器表明自己的身份的话,则,私钥和本地证书也是必需的。
参考 privateKey () 和 setLocalCertificate () 。
将此套接字的SSL配置选项设置为 configuration 的内容。这个函数,会将本地证书、加密算法、私钥和CA证书集设置成 configuration 中所存储的那些东西。
无法设置那些与SSL 状态相关的字段。
此函数是从Qt 4.4 开始引入的。
参考 sslConfiguration () 、 setLocalCertificate () 、 setPrivateKey () 、 setCaCertificates () 和 setCiphers () 。
返回此套接字的SSL配置状态。一个套接字的默认SSL配置选项,就是,使用默认加密算法、默认CA证书集、无本地私钥、无本地证书。
SSL配置选项中还包含一些会随着时间改变且不会发出通知的字段。
此函数是从Qt 4.4 开始引入的。
参考 setSslConfiguration () 、 localCertificate () 、 peerCertificate () 、 peerCertificateChain () 、 sessionCipher () 、 privateKey () 、 ciphers () 和 caCertificates () 。
返回最后 发生的那些SSL 错误的列表。 这个列表与 QSslSocket 通过sslErrors()信号传递的列表相同。如果 在建立加密连接的过程中未发生错误,则,此函数会返回一个空列表。
参考 connectToHostEncrypted () 。
QSslSocket 会在 SSL握手阶段之后 发射这个信号,以表明在验证对方节点的身份时发生了一个或多个错误。 这些错误通常是一种提示,以表明 QSslSocket 无法安全 地验证对方节点的身份。除非 妳采取了措施,否则,在发射了此信号之后,连接会被断开。
如果 妳希望在发生错误的情况下仍然继续建立连接,那么,必须在连接到这个信号的某个信号槽中调用 QSslSocket::ignoreSslErrors ()。如果 妳想在日后访问这个错误信息列表,则,可以调用 sslErrors () ( 不带参数 ) 。
errors 中包含了一或多个错误,它们使得 QSslSocket 无法验证对方节点 的身份。
注意: 在连接到这个信号时不能使用 Qt::QueuedConnection ,否则,调用 QSslSocket::ignoreSslErrors ()将没有效果。
参考 peerVerifyError () 。
这个函数能够获取到由操作系统提供的 CA证书数据库 。 这个函数所返回的 CA证书数据库 ,会被用来初始化 defaultCaCertificates ()所返回的数据库。 妳可以调用 setDefaultCaCertificates (),以便使用妳自己的数据库来替换它。
参考 caCertificates () 、 defaultCaCertificates () 和 setDefaultCaCertificates () 。
Ольга Куриленко
薄 熙来
Your opinions
HxLauncher: Launch Android applications by voice commands