我有一個用於將證書存儲在數據庫中的.NET應用程序的用例。其中一個要求是應用程序拒絕包含私鑰的證書。用戶將上傳證書文件(特別是.CER或.CRT),然後應用程序將其導入爲X509Certificate2對象,以便我可以檢查HasPrivakeKey屬性。是否可以將私鑰包含在.CER證書文件中?
我知道.PFX文件可以包含私鑰,但.CER或.CRT文件是否可以包含私鑰?如果是這樣,我如何生成測試證書以測試應用程序邏輯?
我有一個用於將證書存儲在數據庫中的.NET應用程序的用例。其中一個要求是應用程序拒絕包含私鑰的證書。用戶將上傳證書文件(特別是.CER或.CRT),然後應用程序將其導入爲X509Certificate2對象,以便我可以檢查HasPrivakeKey屬性。是否可以將私鑰包含在.CER證書文件中?
我知道.PFX文件可以包含私鑰,但.CER或.CRT文件是否可以包含私鑰?如果是這樣,我如何生成測試證書以測試應用程序邏輯?
首先,.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
對象
,調用將成功。交換部分,你會看到關於無效格式的異常。
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編碼的證書。
如果我有.pfx文件或.cer + .pvk,我可以使用makecert或openssl來生成上面描述的PEM編碼.cer文件嗎?我知道我可以使用X509Certificate2.PrivateKey.ToXmlString()方法獲得RSA數據並手動創建該文件,但我更願意採用自動方式。 –
我不知道有一種自動的方式來創建這樣的文件。根據我的經驗,人們只是手動連接事物。 – larsks
你有沒有任何參考? –
不確定是否記錄在案。我只是一個在Windows加密方面經驗豐富的人。我知道這種行爲,因爲有'CryptStringToBinary'函數調用將Base64轉換爲二進制形式,並且此函數的行爲如我所述:只返回具有頁眉/頁腳的第一部分,其餘部分將被忽略。 – Crypt32