防止提示输入 PEM 密码

Prevent prompting for PEM passphrase

本文关键字:PEM 密码 输入 提示      更新时间:2023-10-16

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

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

openSSL API允许传递回调以获取密码,但这无法通过Qt包装器访问。有没有其他方法可以防止openSSL提示输入密码?或者这可以以某种方式中断吗?

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

最简单的方法是使私钥无密码。以下是操作方法(假设您有受密码保护的 RSA 密钥):

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

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

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

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

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

我想出了一个解决方案:

OpenSSL 只会在解码函数中未指定任何密码时提示输入密码。正如理查德·摩尔(Richard Moore)在他的回答中指出的那样,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("", 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;
    }
}