简体   繁体   English

验证未分离的PKCS签名

[英]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. 我使用了SignedCms.ComputeSignature和CheckSignature文档中的示例代码(稍作修改)。 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. 如果设置了detached = false ,则签名验证不会因更改的数据而失败。 It happens because data signed were included to the signature object and SignedCms.CheckSignature ignores hash that was calculated from changed data. 发生这种情况是因为将签名的数据包括在签名对象中,并且SignedCms.CheckSignature忽略从更改后的数据计算出的哈希。

Is it possible to use non-detached signature and get signedCms.CheckSignature to take into account hash that was calculated from changed data? 是否可以使用非分离签名并获取signedCms.CheckSignature来考虑从更改后的数据计算出的哈希值? 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. 在非分离模式下,内容位于有效负载中,因此在Decode期间,将丢弃您提供的ContentInfo ,而将使用有效负载中的内容。

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 ) (来自referencesource上的SignedCms.Decode

In detached signature mode the SignedCms data represents a signature (and metadata) over some data you have to provide. 在分离签名模式下,SignedCms数据表示您必须提供的某些数据上的签名(和元数据)。 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). 在嵌入式(非分离)签名模式中,SignedCms数据是单个blob,其中包含数据以及签名(和元数据)。 So sending the CMS object in non-detached mode replaces sending your original data (because the original data is now embedded). 因此,以非分离模式发送CMS对象将代替发送原始数据(因为现在已嵌入原始数据)。

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. 除非要传输的内容实际上只是散列,否则应将实际的data值提供给SignedCms,因为它本身会在计算签名时对其进行哈希处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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