Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 防止提示输入PEM密码短语_C++_Qt_Openssl_Interrupt - Fatal编程技术网

C++ 防止提示输入PEM密码短语

C++ 防止提示输入PEM密码短语,c++,qt,openssl,interrupt,C++,Qt,Openssl,Interrupt,我正在构建一个基于Qt的应用程序,它将通过https与Web服务器进行通信。安装程序应允许使用本地证书和私钥进行客户端身份验证。应用程序必须在没有任何用户交互的情况下运行 现在,当私钥文件受密码短语保护时,我遇到了一个问题: OpenSSL将提示输入密码,阻止整个应用程序 openSSL API允许传递回调以获取密码短语,但这无法通过Qt包装器访问。有没有其他方法可以防止openSSL提示输入密码?或者这会以某种方式被中断吗?查看,在解密私钥时,我看不到任何回调选项 最简单的方法是释放私钥密码。

我正在构建一个基于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时指定密码。构造函数使用密码短语来解密密钥,请参阅下面链接中的文档:


我想出了一个解决方案:

// 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;
    }
}
当解码函数中未指定密码时,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("\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;
    }
}
//切勿使用空PWD,因为它会阻塞。(使用空字符串)
//另外:为未受保护的密钥设置密码仍然可以正确加载密钥!
QByteArray thePwd=pwd.isEmpty()?QByteArray(“\0”,1):pwd.toUtf8();
//尝试所有编码
QList key=QList()

我知道我可以在构造函数中传递密码。但是,当没有为我的应用程序配置密码时,我会遇到一些问题,而文件是受保护的。在这种情况下,没有什么可以传递的,应用程序阻塞了,使用无保护的PK将解决我的问题。虽然这在web服务器上很常见,但我的应用程序位于客户端,我不能强制要求PK文件不受保护……如果私钥确实受到保护,您发布的解决方案将如何工作?它将假定
thePwd
是密码,并将尝试解密私钥,但将失败。它不会提示输入密码短语,因此进程不会被阻止。在这种情况下不能使用密钥,但进程可以对这种情况作出反应并继续,即使只是优雅地关闭。否则,我的BG进程将永远被I/OI阻止。如果您正在编写的客户机是通用客户机,那么这可能不是最有吸引力的选择。但是,既然你是应用程序开发人员,那就由你决定了。在我的应用程序中,我们在环境中混淆密码,让回调函数检索、取消混淆并使用它。这有助于构建无人参与的客户端/服务器应用程序(同时保护私钥)。这不像用户手动输入密码那样强大,但非常接近,因为有人可以劫持密码的唯一方法是劫持用户的终端,在大多数实际情况下,这是不切实际的。