簡體   English   中英

如何使用.Net Core創建PKCS#7分離簽名?

[英]How to create a PKCS#7 detached signature with .Net Core?

我想用.Net Core(2.0)創建PKCS#7分離簽名。

我在這里閱讀了與我的問題或多或少相關的所有答案,並找到了這個這個答案。 所有其他人都無能為力。 第一個例子正是我需要的,但它依賴於.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修改樣本,它會得到與上面代碼相​​同的結果?

我發現另一個討論給了我一個線索。 有一個帶有示例應用程序的GitHub倉庫的鏈接。 我稍微修改了它,現在它按預期工作。 這是代碼:

            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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM