我正在尝试实现一个安全的 TCP 服务器,因此我需要创建一个 X509Certificate2
类的对象来对客户端进行身份验证。
我相信这样的证书对象应该包含私钥(也)以便能够解密传入的消息,不是吗?不管我如何生成证书文件,当我将其文件地址提供给 X509Certificate2
的构造函数时,对象的 HasPrivateKey
属性为 false,并且客户端未经过身份验证!
在 Microsoft 页面 how to use the X509Certificate2
class ,在源代码的注释中,它表明可以使用 makecert
程序生成证书,如下所示:
makecert -r -pe -n "CN=CERT_SIGN_TEST_CERT" -b 01/01/2010 -e 01/01/2012 -sky exchange -ss my
其中 -pe
开关应在证书中包含私钥,但查看生成的文件我可以看出它没有这样做。
由于我在 Ubuntu 中使用 Mono 实现这个软件,所以我想我可以使用 openssl
来代替。因此,请按照 this page 中给出的说明进行操作我创建了一个私钥和一个公钥。 X509Certificate2
类接受公钥,就像它是由 makecert
命令创建的一样,但不接受私钥(构造时会抛出异常)。
有一个relatively old post在 SO 中,它提出了同样的问题,但没有公认的答案。给出的两个建议在 the documentation 中使用两种不同的证书格式:PKCS8 和 PKCS12。很明显,X509Certificate
使用 PKCS7!
总之我很困惑。有人曾经能够在加载私钥的情况下使用X509Certificate2
吗?怎么办?
最佳答案
X509 证书应仅包含公钥。它将公钥与身份绑定(bind)并进行签名。 RFC 5280包含 X509 证书的详细信息。
但是,X509Certificate2
对象可以包含根据 MSDN documentation 的私钥。 .
此外, keystore (例如 PKCS12 keystore )可以包含私钥和相应的证书。
PKCS7 是用于签名和加密消息的规范。
PKCS8 是私钥的规范。
参见PKCS了解不同PKCS标准之间的差异。
上面的 MSDN 链接有一些用于加密和解密文件的示例 C# 代码。它还具有用于生成证书的示例 makecert
命令行。但是,此证书和关联的私钥存储在 Windows 本地用户存储中,因此我不确定这是否可以正确转换为 Ubuntu。
这个SO question也有一些讨论关于使用 PKCS12 keystore 实例化 X509Certificate2
对象,然后访问私钥。这可能是您实现目标的更好方法。您可以使用 openssl 生成私钥、签名证书,并将它们导入 PKCS12 keystore 。您可以使用命令 here 创建 PKCS12 keystore 。 。例如,创建一个文本文件 (file.pem),其中包含私钥的 PEM 格式和相应的 X509 证书。然后运行这个命令:
openssl pkcs12 -export -in file.pem -out file.p12 -name "My Certificate"
此外,在 makecert
文档页面上,还写着“仅用于测试目的”。因此,我不会依赖这些证书来构建生产安全服务器。
关于c# - 在 C# 中实例化一个 X509Certificate 对象,该对象也保存私钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18657311/