我正在构建一个基于Qt的应用程序,它将通过https与网络服务器进行通信。设置应允许使用本地证书和私钥进行客户端身份验证。应用程序必须运行而无需任何用户交互。
现在,当私钥文件受密码保护时,我遇到了问题:
OpenSSL会提示输入密码,阻止整个应用程序!
openSSL API允许传递回调以获取密码,但是这不能通过Qt Wrapper访问。还有另一种方法可以阻止openSSL提示输入密码吗?或者这可以以某种方式被打断?
答案 0 :(得分:0)
在查看online documentation时,我在解密私钥时看不到任何回调选项。
最简单的方法是使私钥无密码。以下是您可以这样做的方法(假设您有受密码保护的RSA密钥):
openssl rsa -in privateKey.pem -out newPrivateKey.pem
此处privateKey.pem
受密码保护,但newPrivateKey.pem
未受密码保护。请注意,虽然这意味着私钥不受保护,但这是执行不间断SSL通信的常用技术(例如,甚至在stunnel
中使用)。假设私钥存储在具有受限权限的目录中,并受操作系统访问策略的保护。
更难的方法是通过直接链接OpenSSL来编写应用程序,而不是通过包装器。这样,您就可以对密码回调进行细粒度控制。
答案 1 :(得分:0)
您可以在构造QSslKey时指定密码。构造函数使用密码来解密密钥,请参阅以下链接中的文档:
答案 2 :(得分: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;
}
}