簡體   English   中英

驗證未分離的PKCS簽名

[英]verify non detached PKCS signature

親愛

請幫助我了解非分離簽名驗證過程。 我使用了SignedCms.ComputeSignature和CheckSignature文檔中的示例代碼(稍作修改)。 這里是

[TestMethod]
public void CheckSignaturePlain()
{
    var x509 = new X509Helper(LogManager.GetLogger("x509"));
    X509Certificate2 certificate = x509.GetCertificate("XML_SIGN_TEST_CERT");
    var str = "quick brown fox jumps over lazy dog";
    var data = Encoding.ASCII.GetBytes(str);
    detached = false; // tests are passed for detached signatures only
    using (var sha256 = new SHA256CryptoServiceProvider()) // One thing though, Microsoft recommends that you avoid using any managed classes.  You should change SHA256Managed to SHA256CryptoServiceProvider. https://blogs.msdn.microsoft.com/winsdk/2015/11/14/using-sha256-with-the-signedxml-class/
    {
        var hash = sha256.ComputeHash(data);
        var signature = Sign(hash, certificate);
        SignCheck(hash, signature);

        try
        {
            data = data.Skip(1).ToArray(); // lets change the data to get broken signature

            var hash2 = sha256.ComputeHash(data);
            SignCheck(hash2, signature);
            Assert.Fail("signature verification should fail");
        }
        catch (CryptographicException ce)
        {
            TestContext.WriteLine(ce.Message);
        }
    }
}

byte[] Sign(byte[] hash, X509Certificate2 cert)
{
    ContentInfo contentInfo = new ContentInfo(hash);
    SignedCms signedCms = new SignedCms(contentInfo, detached);
    CmsSigner cmsSigner = new CmsSigner(cert);
    cmsSigner.IncludeOption = X509IncludeOption.WholeChain;

    signedCms.ComputeSignature(cmsSigner);

    byte[] cmsMessage = signedCms.Encode();
    return cmsMessage;
}

bool detached;

void SignCheck(byte[] hash, byte[] signature)
{
    var contentInfo2 = new ContentInfo(hash);
    var signedCms = new SignedCms(contentInfo2, detached);

    signedCms.Decode(signature);

    signedCms.CheckSignature(true);
}

但是(從我的角度來看)它僅適用於分離的簽名。 如果設置了detached = false ,則簽名驗證不會因更改的數據而失敗。 發生這種情況是因為將簽名的數據包括在簽名對象中,並且SignedCms.CheckSignature忽略從更改后的數據計算出的哈希。

是否可以使用非分離簽名並獲取signedCms.CheckSignature來考慮從更改后的數據計算出的哈希值? 還是應該從非分離簽名中提取簽名數據,計算數據散列並手動比較它們?

我想使用非分離簽名。 來自簽名的簽名數據(實際上是哈希)應該用作抽象層上的消息標識符,該抽象​​層不知道如何為不同類型的對象計算哈希。

在非分離模式下,內容位於有效負載中,因此在Decode期間,將丟棄您提供的ContentInfo ,而將使用有效負載中的內容。

if (!this.Detached) {
    Oid contentType = PkcsUtils.GetContentType(m_safeCryptMsgHandle);
    byte[] content = PkcsUtils.GetContent(m_safeCryptMsgHandle);
    m_contentInfo = new ContentInfo(contentType, content); 
}

(來自referencesource上的SignedCms.Decode

在分離簽名模式下,SignedCms數據表示您必須提供的某些數據上的簽名(和元數據)。 使用標准的密碼簽名行為,它將獲取輸入數據,對其進行哈希處理,並對散列執行私鑰操作以生成簽名。

在嵌入式(非分離)簽名模式中,SignedCms數據是單個blob,其中包含數據以及簽名(和元數據)。 因此,以非分離模式發送CMS對象將代替發送原始數據(因為現在已嵌入原始數據)。

除非要傳輸的內容實際上只是散列,否則應將實際的data值提供給SignedCms,因為它本身會在計算簽名時對其進行哈希處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM