如何在Mac OSX上使用Qt中的pkcs12/pfx执行成功的SSL加密?

问题描述:

Qt初学者和开发跨平台应用程序,需要从服务器和客户端进行SSL身份验证。基于.pem的加密适用于Linux,Android,Windows。但是,Mac OSX存在问题。我们的代码看起来像下面:如何在Mac OSX上使用Qt中的pkcs12/pfx执行成功的SSL加密?

QFile privateKeyFile(":/Certificate.pem"); // --> has certificate + key 
privateKeyFile.open(QIODevice::ReadOnly | QIODevice::Text);  
setLocalCertificateChain(QSslCertificate::fromPath(":/Certificate.pem", QSsl::Pem)); 
setPrivateKey(QSslKey(privateKeyFile.readAll(), QSsl::Rsa)); 

在上面的代码中privateKey().isNull()回报true为Mac。当我们提到this post时,它表示Mac不支持基于.pem的加密。

卷曲的安全传输后端仅支持采用PKCS#12(P12)格式的客户端ID;它不支持PEM格式的客户端ID,因为Apple不允许我们使用PEM格式的身份文件创建安全身份,而不使用私有API。而且我们不能使用私有API,因为使用私有API的应用不允许在Apple的任何应用商店中使用。

由于我的理解有限,我解释说.pem不适合与服务器进行SSL通信。如果它错了,请阻止我!

因此,我们决定移动到所有平台的.pfx。我们已经有一个带有密码的.pfx文件。我们将上面的代码转换为与.pfx兼容(即“Certificate.pfx”,我们将此旧文件与“Certificate.pem”一起)。我们尝试了QSsl::Der而不是QSsl::Pem。但如预期的那样,它没有奏效。但是,也没有加密错误,但我们确信我们做错了什么。 :-)

我们提到这篇文章,并尝试从.pem重新生成.pfx,但这也没有帮助。
QSslCertificate::importPkcs12 fails to parse PFX file
在上述情况下,QSslCertificate::importPkcs12()对原始.pfx文件返回false。即使我们从命令行生成新的.pfx,上述功能也失败了。

问题:有人可以帮助确切的方式与服务器执行.pfx加密吗?
.pem认证也很好。

注意

  • 服务器支持.PFX &。质子交换膜。我们用常规的C OpenSSL库进行了确认。但我们想用Qt来实现它。
  • 我们是开放的比.PFX其他格式,它们应该在所有的平台上工作
+0

非常混乱。你在做SSL客户端身份验证吗?如果你是这种情况,这很少见。如果你不是,那么你没有私钥,所以你不需要Pkcs#12。 –

+0

@JamesKPolk,我对SSL的知识有限。简而言之,我们有一个使用C函数来验证服务器的旧代码。它使用一个.pfx证书,该证书被转换为.pem,然后与服务器交换。现在我们必须将该代码移植到Qt。使用.pem,它的工作原理已经在上面的代码中演示过了。但是,它仅在Mac中无法使用。在网上搜索时,我们得到了一个github帖子,这表明Mac不支持.pem,这在Qn中也有提到。所以我们想回到.pfx。现在我们不知道该怎么做。对不起,不够清楚。 – iammilind

+0

您是否试过将证书和客户端密钥文件分开,将它们转换为DER格式并逐一加载它们? – nothingam

免责声明:我从我的脑海里的顶部写这个,因为我个人不拥有一台Mac,不能再次验证它。

在我上一份工作中,一两年前我们遇到过这个问题。这一切归结为苹果放弃对OpenSSL的支持。

因此,Qt在Mac上用Qt5.6从OpenSSL后端切换到安全传输后端。现在安全传输实施缺乏一些功能。例如,我们无法加载私钥pem文件。我认为从PKCS#8切换到PKCS#1有帮助,它们都可以存储在.pem文件中,并且看起来几乎完全相同,因此花了一段时间才弄清楚。

我们也注意到,一个成功加载的私钥将存储在Mac的密钥存储区内,并且可以从用户那里查看和导出,这也是我们不想要的。

我们终于重新编译了QtNetwork模块,使用OpenSSL代替安全传输。您将需要为此提供OpenSSL,因为OSX不再包含标头。我觉得自制装置足够了。除此之外,编译出奇的无痛和快速,因为你只需要编译一个小模块,而不是整个Qt。

做到这一点,最简单的方法是:

  1. 下载了Qt版本的源分布,你正在运行
  2. ./configure它使用OpenSSL(在-openssl开关我相信)
  3. cd进入network文件夹
  4. make
  5. 复制生成的QtNetwork.framework在您的Qt安装里面并且替换现有的。

随着一切按预期工作。