简体   繁体   中英

verify non detached PKCS signature

Dears

Please help me to understand non detached signature validation process. I've used sample code (slightly modified) from SignedCms.ComputeSignature and CheckSignature documentation. Here it is

[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);
}

However it works properly (from my point of view) only for detached signatures. If detached = false is set then signature verification does not fail for changed data. It happens because data signed were included to the signature object and SignedCms.CheckSignature ignores hash that was calculated from changed data.

Is it possible to use non-detached signature and get signedCms.CheckSignature to take into account hash that was calculated from changed data? Or I should extract signed data from non-detached signature, calculate hash over data and compare them manually?

I'd like to use non-detached signature. Signed data from the signature (hash actually) should be used as message identifier on abstraction layer that has no idea how to calculate hash for different kind of objects.

In non-detached mode the content is within the payload, so during Decode the ContentInfo you provided is discarded and the one from within the payload is used instead.

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

(from SignedCms.Decode on referencesource )

In detached signature mode the SignedCms data represents a signature (and metadata) over some data you have to provide. Using standard cryptographic signature behaviors it takes the input data, hashes it, and performs a private key operation on the hash to generate the signature.

In embedded (non-detached) signature mode the SignedCms data is a single blob which contains the data as well as the signature (and metadata). So sending the CMS object in non-detached mode replaces sending your original data (because the original data is now embedded).

Unless the thing you want to transport is actually just the hash, you should feed SignedCms the actual data value, since it hashes it itself as part of computing the signature.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM