2016-06-20 55 views
0

我不太瞭解如何使用PKCS#7消息。如何檢查SignedCms信封的簽名?

我用一個X509Certificate2標記了一些字節數組,並且還得到了一個字節數組。

byte[] data = new byte[5] { 110, 111, 112, 113, 114 }, signedData; 

X509Certificate2 cert = new X509Certificate2(certPath, password); 

ContentInfo content = new ContentInfo(data); 
SignedCms envelope = new SignedCms(content); 
CmsSigner cmsSigner = new CmsSigner(cert); 
envelope.ComputeSignature(cmsSigner); 
signedData = envelope.Encode(); 

signedData被髮送到某個遠程收件人,他得到SignedCms信封。

SignedCms envelope = new SignedCms(); 
envelope.Decode(signedData); 

他如何解碼信封?他不會將我的公鑰作爲參數。我的公鑰在SignerInfo屬性的信封中,但是有什麼理由讓任何人都可以用整個簽名來替換它?

收件人可以用我的公鑰確認信封的實際發件人是我嗎?

有方法envelope.CheckSignature(new X509Certificate2Collection(certificate), true);但我試圖使用錯誤的證書,並沒有拋出異常。

回答

0

PKCS#7本身就是一個簽名,它可以被替換嗎?當然。 envelope.CheckSiganture只是驗證pkcs#7具有正確的格式和長度,換句話說,檢查pkcs#7是否構建良好。

廣泛地說,你需要實現一個PKI(私鑰基礎設施)。一方面,您使用公鑰構建pkcs#7,另一方面您必須驗證pkcs#7實際上是否擁有您認可爲自己的有效證書。您必須實施OCSP來驗證這些證書,並且如果所有內容都檢查完畢,您必須向第三方請求時間戳以證明您的pkcs#7。您還需要一個庫(數據庫)來跟蹤一切:pkcs#7,數據散列,時間戳,原始數據,ocsp響應...

但是,如果您只想知道如何識別pkcs# 7,您可以使用各種工具來解碼PKCS#7,此操作會返回其中包含的所有信息。或者你可以使用C#創建你自己的。

0

甲PKCS#7/CMS/S/MIME簽名的消息是一個數據容器,其具有(除了一些其他元數據):

 
EncapsulatedContentInfo 
    ContentInfoType 
    EncapsulatedContent (the message bytes) 
Certificates (Optional) 
CRLs (Optional) 
SignerInfos 
    DigestAlgorithm (e.g. SHA-1) 
    SignedAttributes (Optional, allows other context information to be signed) 
    SignatureAlgorithm (e.g. RSA, DSA, ECDSA) 
    SignatureValue (the signature bytes) 
    UnsignedAttributes (Optional, allows for after-signing information, like counter-signatures) 

(這是RFC 2630 (Cryptographic Message Syntax) Section 5摘要)

SignedCms.Decode讀取編碼的消息並填充成員。消息的每個直接簽名都可以從SignedCms :: SignerInfos屬性中讀取(反簽名者或已簽名的實體,他們目睹了原始簽名,可以從SignerInfo :: CounterSignerInfos中讀取)。

當您調用SignedCms.CheckSignature時,它會檢查每個SigerInfo並驗證簽名是否可以被成功驗證(或引發異常),並且每個簽署者簽名都可以計算出來。

它不知道的是,任何簽名者「有道理」。對於這種檢查,您需要遍歷每個SignerInfo並查看(例如)證書屬性;然後執行適應性檢查:

  • 也許是一個預先登記的公共密鑰
  • 也許鏈高達公知的根或中間CA
  • 也許它具有某種擴展的,其示出了它以適合

這部分SignedCms實際上不適合你,因爲與TLS的主機名驗證不同,對於消息沒有默認的「合適」概念。

如果您想評估單個簽名者的簽名,您可以調用SignedInfo :: CheckSignature,但如果您也稱爲SignedCms :: CheckSignature,則這是多餘的。

有方法envelope.CheckSignature(new X509Certificate2Collection(certificate),true);但我試圖使用錯誤的證書,並沒有拋出異常。

extraCerts過載提供額外證書。有效的方法是使用不嵌入簽署者證書的SignedCms消息,使其保留給接收方以提前知道有效證書(例如,使用預先註冊證書的每用戶數據庫)。您沒有得到例外,因爲在提供的證書集合中找到了正確的證書。

您可以通過X509Certificate2Collection.Import方法查看提供的證書集合中的內容;他們可以讀取PKCS#7簽名數據消息並使用可選的嵌入式證書填充該集合。

相關問題