2015-09-04 67 views
0

我有一个用于将证书存储在数据库中的.NET应用程序的用例。其中一个要求是应用程序拒绝包含私钥的证书。用户将上传证书文件(特别是.CER或.CRT),然后应用程序将其导入为X509Certificate2对象,以便我可以检查HasPrivakeKey属性。是否可以将私钥包含在.CER证书文件中?

我知道.PFX文件可以包含私钥,但.CER或.CRT文件是否可以包含私钥?如果是这样,我如何生成测试证书以测试应用程序逻辑?

回答

1

首先,.NET不支持带私钥的PEM格式。但是,如果提供了这种格式,则定义了以下结果:

1)如果证书头/页脚是文件中的第一个,.NET将忽略文件的其余内容(例如,私钥信息)并创建有效的对象X509Certificate2没有私钥(因为PKCS#1和PKCS#8密钥不受支持,被构造函数X509Certificate2调用的CryptoAPI函数支持,但有一些函数可以与PKCS#1一起使用)。 2)如果私钥头/页脚是文件中的第一个,.NET将引发关于无效证书的异常。

p.s.仅当使用Base64编码并且每个部分使用页眉和页脚时(例如,-----BEGIN CERTIFICATE----------END CERTIFICATE-----),这种组合才是可能的。无需使用PKCS#12容器就可以将它们以二进制形式组合起来。


更新:如果你想测试它自己,这里就是这样的PEM文件的例子:

-----BEGIN CERTIFICATE----- 
MIIEIDCCA+CgAwIBAgIUHSle8379VhDdbksPu2S6q+CkCMQwCQYHKoZIzjgEAzAjMSEwHwYDVQQD 
ExhUb2tlbiBTaWduaW5nIFB1YmxpYyBLZXkwHhcNMTMwNzAzMTkzNDIzWhcNMTMwNzEwMTkzNDIz 
WjAtMSswKQYDVQQDHiIAYgBiADEANAAxADkAYQAyAGMAZgBjADEAZQAwADAAOAAAMIGfMA0GCSqG 
SIb3DQEBAQUAA4GNADCBiQKBgQDbU9p4AwJy2RZxHYMXKalKv6K6cwrUB2RnFHZbelPgggfJyIZm 
kL5pbB7u6tFYCBiNcMR6t8ItfVsi9iL33Uuluov7YZ3DPjRAVx4MZqXN3YR9bhzmOZpMgzKNxzoR 
Kdhxy3qWYFAKdYZ9P1ln+9aUGJE3f1MuM7OPg1vWFUZ2VwIDAQABo4ICoDCCApwwDgYDVR0PAQH/ 
BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMIIB/wYDVR0gBIIB9jCCAfIwggHuBgorBgEEAYI3 
MwMCMIIB3jCCAdoGCCsGAQUFBwICMIIBzB6CAcgATQBpAGMAcgBvAHMAbwBmAHQAIABkAG8AZQBz 
ACAAbgBvAHQAIAB3AGEAcgByAGEAbgB0ACAAbwByACAAYwBsAGEAaQBtACAAdABoAGEAdAAgAHQA 
aABlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACAAZABpAHMAcABsAGEAeQBlAGQAIABpAG4AIAB0 
AGgAaQBzACAAYwBlAHIAdABpAGYAaQBjAGEAdABlACAAaQBzACAAYwB1AHIAcgBlAG4AdAAgAG8A 
cgAgAGEAYwBjAHUAcgBhAHQAZQAsACAAbgBvAHIAIABkAG8AZQBzACAAaQB0ACAAbQBhAGsAZQAg 
AGEAbgB5ACAAZgBvAHIAbQBhAGwAIABzAHQAYQB0AGUAbQBlAG4AdABzACAAYQBiAG8AdQB0ACAA 
dABoAGUAIABxAHUAYQBsAGkAdAB5ACAAbwByACAAcwBhAGYAZQB0AHkAIABvAGYAIABkAGEAdABh 
ACAAcwBpAGcAbgBlAGQAIAB3AGkAdABoACAAdABoAGUAIABjAG8AcgByAGUAcwBwAG8AbgBkAGkA 
bgBnACAAcAByAGkAdgBhAHQAZQAgAGsAZQB5AC4wUwYDVR0jBEwwSoAUaISoloVlkV/P4JGkgUGj 
gzjrVSChJ6QlMCMxITAfBgNVBAMTGFRva2VuIFNpZ25pbmcgUHVibGljIEtleYIJAKs+FSwkyech 
MB0GA1UdDgQWBBQQOhVxyI6GdpyHsij3PQU1ep0k7DAJBgcqhkjOOAQDAy8AMCwCFAPO2/xwhf37 
xELxJhiMFEGvQXmgAhRNgAk/L2YWq1SlQ7Ax/XH5c8Ep0w== 
-----END CERTIFICATE----- 
-----BEGIN PRIVATE KEY----- 
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANtT2ngDAnLZFnEdgxcpqUq/orpz 
CtQHZGcUdlt6U+CCB8nIhmaQvmlsHu7q0VgIGI1wxHq3wi19WyL2IvfdS6W6i/thncM+NEBXHgxm 
pc3dhH1uHOY5mkyDMo3HOhEp2HHLepZgUAp1hn0/WWf71pQYkTd/Uy4zs4+DW9YVRnZXAgMBAAEC 
gYAKMnja0ZEAk/VGJxAcOJSlZAmFz6l2OC3D2SCzmhliO8lu6ULOa/ZeYmeBxisbg6zYjqCj7/04 
LjbZhkYT7hcBNH6lns7yGZzkdly4y0Ud7tjsM+E31Y0Wb7jh/t3pvETUtTUxwhGT5nheiE3iDDj1 
RQATdYxAL57Hr5R1+jc5SQJBAPjrJtZN21JJSlrpZIGB2KKrK6thy/oMWGsw1B3TyZWZt1Q06Fe3 
MwTrJ1K4YWRyhRy9ib4yqQKMq0mcMqPCMGMCQQDhkTGDSG+lbZnhjop9YwmmJpxiaXZELphc9Tr8 
Kf0f6vcfe4mh0OIwpatlqaZiCh5yQwv4GTuwGsRv199f8LJ9AkEA2qeuAPh5XUoWL8/vQrgt9Y7J 
GI4a4PaxQM+utNjSrkBOQ4EKS+sYvQxYCZj/rH3QolN4yQO1ZRDucgXskd9GIwJBANk3n+2j6Nfu 
trwuLxFWOSmGjxx6IMjB8jm6ckX5DWgaNkZcCgsJA3kDYQ2ylKZexjkUdcdCTWdmL3rg8JwMR2UC 
QQCXhPLLIjtcdHzUHjy9dqzPyATduAmD23K7UPBDytFRyNcvUE+0Yfw3Lnvd/wATuUiFqHkhjD4v 
qkICcfVum6Yi 
-----END PRIVATE KEY----- 
当实例从这个文件的 X509Certificate2对象

,调用将成功。交换部分,你会看到关于无效格式的异常。

+0

你有没有任何参考? –

+0

不确定是否记录在案。我只是一个在Windows加密方面经验丰富的人。我知道这种行为,因为有'CryptStringToBinary'函数调用将Base64转换为二进制形式,并且此函数的行为如我所述:只返回具有页眉/页脚的第一部分,其余部分将被忽略。 – Crypt32

1

PEM格式的X509证书只是一个文本文件。这是不寻常的人证书和密钥追加到同一个文件,所以你最终的东西,看起来像:

-----BEGIN CERTIFICATE----- 
...certificate data... 
-----END CERTIFICATE----- 
-----BEGIN RSA PRIVATE KEY----- 
...key data... 
-----END RSA PRIVATE KEY----- 

软件期待阅读私钥会忽略BEGIN RSA PRIVATE KEY/END RSA PRIVATE KEY之外的一切行和期望读取公共证书的软件将忽略BEGIN CERTIFICATE/END CERTIFICATE行之外的所有内容。

在这种情况下测试私钥的最简单方法是查找BEGIN RSA PRIVATE KEY标记。

我不认为有可能以这种方式连接DER编码的证书。

+0

如果我有.pfx文件或.cer + .pvk,我可以使用makecert或openssl来生成上面描述的PEM编码.cer文件吗?我知道我可以使用X509Certificate2.PrivateKey.ToXmlString()方法获得RSA数据并手动创建该文件,但我更愿意采用自动方式。 –

+0

我不知道有一种自动的方式来创建这样的文件。根据我的经验,人们只是手动连接事物。 – larsks

相关问题