2016-11-18 56 views
1

PKCS7_verify()手冊頁指出爲什麼OpenSSL的PKCS7_verify()需要「smimesign」證書目的?

...Each signer's certificate is chain verified using the smimesign purpose...

爲什麼恰恰總是需要這一個目的?我瞭解它,以便籤名的PKCS7結構可以用於許多事情,S/MIME只是其中之一。

如果我的簽名證書extendedKeyUsage擴展名中沒有smimeSign,則PKCS7_verify()失敗。我需要手動調整purpose才能進行驗證。我在這裏錯過了什麼嗎?

回答

2

只需驗證簽名,檢查簽名者的證書是否真實,並確保鏈接導致受信任的根目錄是不夠的。任何驗證碼也必須確保證書持有者有權爲特定目的執行簽名。獲得具有smimeSign特權的證書的審覈要比對代碼簽名證書進行審查嚴格得多。

想象一下,一家軟件開發公司,每位員工都已獲得電子郵件簽名和加密證書。該公司還發佈一個軟件產品,並提供其產品的PKCS#7簽名分發包。如果PKCS#7驗證功能沒有檢查簽名證書的用途(在這種情況下,我們想要codesign),那麼公司僱用的壞角色可能會創建一個受損的軟件產品版本,並用它們簽名電子郵件證書(其中只有目的smimesign。)

在OpenSSL的pkcs7_verify()的情況下,API設計的明確要求一個暗示一個目的,而不是要傳遞的,並smimeSign被選爲默認。我猜測由於S/MIME是PKCS#7最常見的用途,它是有道理的,它允許某人在大多數使用情況下驗證PKCS#7,而無需瞭解extendedKeyUsage

[不如我原來的答覆,以解決您的預編輯的問題「我可以指定我想驗證一個PKCS7簽名反對其他目的」:]

證書可以包含(可選的)稱爲「擴展密鑰使用」的屬性。該屬性用於指示允許使用哪種證書。一些可能X509.v3用法是:

  • serverAuthentication
  • clientAuthentication
  • 代碼簽名
  • emailProtection
  • ipSecEndSystem
  • ipSecTunnel
  • 時間戳
  • ocspSigning
  • smartCardLogin
  • pkiPeerAuth

您可以檢查x509v3_config手冊頁鍵使用標誌即OpenSSL是知道的。

PKCS#7是一種通用容器格式,允許對容器的內容進行簽名和/或加密。 S/MIME使用PKCS#7簽署和/或加密電子郵件消息,在這種情況下,使用的證書應具有emailProtection用法。

如果您想分發一些代碼,並且您希望確保收件人可以驗證發行版是否來自您並且保持不變,那麼可以使用PKCS#7進行發佈,在這種情況下,您的證書應該具有codeSigning增強密鑰用法屬性。 證書有可能具有多個密鑰用法,但總的來說,對於不同的使用類型有一個單獨的密鑰(以及因此證書)是一個好主意。

在命令行中,Openssl支持在使用「openssl smime」命令時指定證書的所需目的。例如,

openssl smime -verify -in myfile.p7b -inform DER -out my-p7-content -purpose any 

將驗證文件「我file.p7p」的簽名,它會返回PKCS#7容器的文件「我-P7內容」的內容,它將接受任何有效證書,無論其指示的目的是什麼。 (用於任何)。請注意,smime的openssl手冊頁沒有列出作爲選項的-purpose開關,但確實支持它。

由於您以編程方式引用了PKCS7_verify API文檔,因此您可以在設置X509_STORE對象時通過X509_VERIFY_PARAM_set_purpose方法指定用途。下面的片段應該給你一個流程的概念:

X509_STORE store; 
int purpose; 

store = X509_STORE_new(); 
verify_params = X509_Store_get0_param(store); 
purpose = X509_PURPOSE_get_by_sname("sslclient"); 
X509_VERIFY_PARAM_set_purpose(verify_params, purpose) 
... 
PKCS7_verify(..., store, ...); 

這將在驗證時將目的設置爲SSL客戶端。

+0

謝謝你的詳細解答;但我的問題不是**如何更改**驗證目的。這是關於**爲什麼我應該這樣做**。 (我更新了這個問題,以便更具體地說明這一點)。我的用例實際上就是您所指的:PKCS#7用於簽名軟件,簽名證書具有'KeyUsage = critical,digitalSignature'和'ExtendedKeyUsage = codeSigning'。 'PKCS7_verify()'在使用此證書籤名時失敗(如果我添加'smimesign'目的,則成功)。爲什麼這個功能總是需要一個特定的「目的」? – user3608247

+0

@ user3608247我已更新我的答案以解決您編輯的問題。我在「如何」中留下了原始答案,因爲對於臨時用戶來說,如何以編程方式來做這件事並不是太明顯,對某些人可能會有用。 –