繁体   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