【问题标题】:How can I check signature of a SignedCms envelope?如何检查 SignedCms 信封的签名?
【发布时间】:2016-10-22 04:21:41
【问题描述】:

我不太了解如何处理 PKCS#7 消息。

我用我拥有的 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);方法,但我尝试使用错误的证书,没有抛出异常。

【问题讨论】:

    标签: c# digital-signature x509certificate2 pkcs#7


    【解决方案1】:

    PKCS#7 / CMS / S/MIME 签名消息是一个数据容器,它具有(除了一些其他元数据):

    封装内容信息 内容信息类型 EncapsulatedContent(消息字节) 证书(可选) CRL(可选) 签名者信息 摘要算法(例如 SHA-1) SignedAttributes(可选,允许对其他上下文信息进行签名) 签名算法(例如 RSA、DSA、ECDSA) SignatureValue(签名字节) UnsignedAttributes(可选,允许签名后的信息,如会签)

    (这是RFC 2630 (Cryptographic Message Syntax) Section 5的总结)

    SignedCms.Decode 读取编码消息并填充成员。消息的每个直接签名者都可以从 SignedCms::SignerInfos 属性中读取(可以从 SignerInfo::CounterSignerInfos 中读取会签者或已签名的实体,他们见证了原始签名)。

    当您调用 SignedCms.CheckSignature 时,它​​会检查每个 SigerInfo 并验证签名是否可以成功验证(或引发异常),以及是否可以计算出每个会签人的签名。

    它不知道任何签名者都“有意义”。对于该检查,您需要遍历每个 SignerInfo 并查看(例如)证书属性;然后执行适用性检查:

    • 可能是预先注册的公钥
    • 也许它链接到一个众所周知的根或中间 CA
    • 也许它有某种扩展表明它是合适的

    这部分 SignedCms 实际上无法为您完成,因为没有“适合”消息的默认概念,这与 TLS 的主机名验证不同。

    如果您想评估单个签名者的签名,您可以调用 SignedInfo::CheckSignature,但如果您还调用了 SignedCms::CheckSignature,则这是多余的。

    有方法信封.CheckSignature(new X509Certificate2Collection(certificate), true);但是我尝试使用错误的证书并没有抛出异常。

    extraCerts 重载提供额外 证书。拥有不嵌入签名者证书的 SignedCms 消息是有效的,让接收者提前知道有效证书(例如,使用预注册证书的每个用户数据库)。您没有遇到异常,因为在提供的证书集合中找到了正确的证书。

    您可以通过 X509Certificate2Collection.Import 方法查看提供的证书集合中的内容;他们可以读取 PKCS#7 签名数据消息并使用可选的嵌入式证书填充集合。

    【讨论】:

      【解决方案2】:

      PKCS#7 本身只是一个签名,可以替换吗?当然。信封.CheckSiganture 只是验证 pkcs#7 具有正确的格式和长度,换句话说,检查 pkcs#7 是否构造良好。

      概括地说,您需要实施 PKI(私钥基础设施)。一方面,您使用公钥构建您的 pkcs#7,另一方面,您必须验证您拥有的 pkcs#7 是否确实具有您认为是您自己的有效证书。您必须实施 OCSP 来验证这些证书,如果一切正常,您应该并且必须向第三方请求时间戳以保证您的 pkcs#7。此外,您还需要一个保管库(数据库)来跟踪所有内容:pkcs#7、数据哈希、时间戳、原始数据、ocsp 响应...

      但是,如果您只想知道如何识别 pkcs#7,可以使用各种工具来解码 PKCS#7,此操作会返回其中包含的所有信息。或者您可以使用 c# 创建自己的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-11
        • 2022-11-05
        • 1970-01-01
        相关资源
        最近更新 更多