0

我正在构建一个基于 Qt 的应用程序,它将通过 https 与网络服务器进行通信。该设置应允许使用本地证书和私钥进行客户端身份验证。应用程序必须在没有任何用户交互的情况下运行。

现在,当私钥文件受密码保护时,我遇到了一个问题:
OpenSSL 会提示输入密码,从而阻止整个应用程序!

openSSL API 允许通过回调来获取密码,但是通过 Qt Wrapper 无法访问。还有其他方法可以防止 openSSL 提示输入密码吗?或者这可以以某种方式被打断?

4

3 回答 3

0

您可以在构造 QSslKey 时指定密码。构造函数采用一个密码短语,用于解密密钥,请参阅以下链接中的文档:

http://qt-project.org/doc/qt-4.8/qsslkey.html#QSslKey-2

于 2013-09-28T09:54:38.167 回答
0

我想出了一个解决方案:

当解码函数中没有指定密码时,OpenSSL 只会提示输入密码。正如理查德摩尔在他的回答中指出的那样,QSslKey有一个构造函数,您可以在其中传递密码。

只要在此处传递一个非空字符串,OpenSSL 就不会提示输入密码。加:如果密钥不受保护,密码将被忽略。因此,我只是确保传递了一个非空字符串,所以这是我的解决方案:

// Never use empty PWD, as this blocks. (Use null-string)
// PLUS: setting a password for a non-protected key still correctly loads the key!
QByteArray thePwd = pwd.isEmpty() ? QByteArray("\0", 1) : pwd.toUtf8();

// Try all encodings
QList<QSslKey> keys = QList<QSslKey>()
    << QSslKey( theKey, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, thePwd )
    << QSslKey( theKey, QSsl::Rsa, QSsl::Der, QSsl::PrivateKey, thePwd )
    << QSslKey( theKey, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, thePwd )
    << QSslKey( theKey, QSsl::Dsa, QSsl::Der, QSsl::PrivateKey, thePwd );

// Find a valid encoding
foreach ( QSslKey k, keys ) {
    if ( !k.isNull() ) {
        ret = k;
        break;
    }
}
于 2013-09-30T09:35:25.907 回答
0

在查看在线文档时,我在解密私钥时看不到任何回调选项。

最简单的方法是使私钥免密码。以下是你可以做到的(假设你有受密码保护的 RSA 密钥):

openssl rsa -in privateKey.pem -out newPrivateKey.pem

这里privateKey.pem有密码保护,但newPrivateKey.pem不是。请注意,虽然这意味着私钥不受保护,但这是进行不间断 SSL 通信的常用技术(即使在stunnel例如使用)。假设私钥存储在具有受限权限并受操作系统访问策略保护的目录中。

更难的方法是通过直接与 OpenSSL 链接而不是通过包装器来编写应用程序。这样,您就可以对密码回调进行细粒度控制。

于 2013-09-27T19:08:09.440 回答