【问题标题】:How to create a PKCS#7 detached signature with .Net Core?如何使用 .Net Core 创建 PKCS#7 分离签名?
【发布时间】:2017-12-25 16:11:45
【问题描述】:

我想用 .Net Core (2.0) 创建 PKCS#7 分离签名。

我在这里阅读了与我的问题或多或少相关的所有答案,并找到了thisthis 的答案。其他人都束手无策。第一个示例完全符合我的需要,但它依赖于 .NetFramework。
第二个使用 Bouncy Castle 库并做一些不同但相似的事情。我发现Portable.BouncyCastle 项目在.Net Core 上运行。据我所知,这是我唯一的选择。

这是第一个示例的代码,经过一些修改:

    string s = "data string";
    byte[] data = Encoding.UTF8.GetBytes(s);        
    X509Certificate2 certificate = null;
    X509Store my = new X509Store(StoreName.My,StoreLocation.CurrentUser);
    my.Open(OpenFlags.ReadOnly);
    certificate = my.Certificates.Find(X509FindType.FindByThumbprint, "my thumbprint", false)[0];
    if (certificate == null) throw new Exception("No certificates found.");

    ContentInfo content = new ContentInfo(new Oid("1.2.840.113549.1.7.1"),data);
    SignedCms signedCms = new SignedCms(content, true);

    CmsSigner signer = new CmsSigner(certificate);
    signer.DigestAlgorithm = new Oid("SHA256"); 

    // create the signature
    signedCms.ComputeSignature(signer);
    return signedCms.Encode();

在我的情况下它工作正常。 signedCms.Encode() 返回 1835 字节,此值通过验证。

但如果我使用 BounceCastle,我会得到另一个结果。这是代码:

                X509Certificate2 certificate = null;
        X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        my.Open(OpenFlags.ReadOnly);

        certificate = my.Certificates.Find(X509FindType.FindByThumbprint, "my thumbprint", false)[0];
        var privKey = DotNetUtilities.GetRsaKeyPair(certificate.GetRSAPrivateKey()).Private;
        var cert = DotNetUtilities.FromX509Certificate(certificate);

        var content = new CmsProcessableByteArray(data);

        var generator = new CmsSignedDataGenerator();

        generator.AddSigner(privKey, cert, CmsSignedGenerator.EncryptionRsa, CmsSignedGenerator.DigestSha256);

        var signedContent = generator.Generate(content, false);
        return signedContent.GetEncoded();

signedContent.GetEncoded() 返回 502 字节,此结果无法验证。我知道我做错了什么,但我不知道是什么。

我应该如何使用 Bouncy Castle 修改示例,以获得与上面代码相​​同的结果?

【问题讨论】:

  • 您在使用 CmsSignedDataGenerator 时没有指定 Oid,可能是这个原因吗?
  • 值得一提的是:SignedCms 已添加到 .NET Core 2.1。

标签: c# .net-core bouncycastle pkcs#7


【解决方案1】:

我找到了另一个discussion,这给了我一个线索。有一个带有示例应用程序的GitHub repo 链接。我稍微修改了一下,现在它可以按预期工作了。代码如下:

            X509Certificate2 certificate = null;
        X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        my.Open(OpenFlags.ReadOnly);

        certificate = my.Certificates.Find(X509FindType.FindByThumbprint, "thumbprint", false)[0];
        var privKey = DotNetUtilities.GetRsaKeyPair(certificate.GetRSAPrivateKey()).Private;
        var cert = DotNetUtilities.FromX509Certificate(certificate);

        var content = new CmsProcessableByteArray(data);

        var generator = new CmsSignedDataGenerator();

        generator.AddSigner(privKey, cert, CmsSignedGenerator.EncryptionRsa, CmsSignedGenerator.DigestSha256);

        var signedContent = generator.Generate(content, false);

        string hashOid = OID.SHA256;

        var si = signedContent.GetSignerInfos();
        var signer = si.GetSigners().Cast<SignerInformation>().First();

        SignerInfo signerInfo = signer.ToSignerInfo();

        Asn1EncodableVector digestAlgorithmsVector = new Asn1EncodableVector();
        digestAlgorithmsVector.Add(
            new AlgorithmIdentifier(
                algorithm: new DerObjectIdentifier(hashOid),
                parameters: DerNull.Instance));

        // Construct SignedData.encapContentInfo
        ContentInfo encapContentInfo = new ContentInfo(
            contentType: new DerObjectIdentifier(OID.PKCS7IdData),
            content: null);

        Asn1EncodableVector certificatesVector = new Asn1EncodableVector();
        certificatesVector.Add(X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetEncoded())));

        // Construct SignedData.signerInfos
        Asn1EncodableVector signerInfosVector = new Asn1EncodableVector();
        signerInfosVector.Add(signerInfo.ToAsn1Object());

        // Construct SignedData
        SignedData signedData = new SignedData(
            digestAlgorithms: new DerSet(digestAlgorithmsVector),
            contentInfo: encapContentInfo,
            certificates: new BerSet(certificatesVector),
            crls: null,
            signerInfos: new DerSet(signerInfosVector));

        ContentInfo contentInfo = new ContentInfo(
            contentType: new DerObjectIdentifier(OID.PKCS7IdSignedData),
            content: signedData);

        return contentInfo.GetDerEncoded();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多