2017-12-25 19 views
2

Ich möchte PKCS # 7 losgelöste Signatur mit .NET Core (2.0) erstellen.Wie erstellt man eine PKCS # 7-Signatur mit .Net Core?

las ich alle Antworten hier mehr oder weniger relevant für mein Problem und fand this und this Antworten. Alle anderen waren hilflos. Das erste Beispiel tut genau das, was ich brauche, aber es basiert auf .NetFramework.
Die zweite verwenden Bouncy Castle Bibliothek und tun etwas anderes, aber ähnliches. Ich fand Portable.BouncyCastle Projekt arbeitete an .Net Core. Wie ich es verstehe, ist es die einzige Option für mich.

Dies ist der Code von dem ersten Beispiel mit einigen Änderungen:

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

Es funktioniert in meinem Fall in Ordnung. signedCms.Encode() gibt 1835 Bytes zurück, und dieser Wert besteht die Validierung.

Aber wenn ich BounceCastle verwende, bekomme ich ein anderes Ergebnis. Dies ist der Code:

   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() gibt 502 Byte und dieses Ergebnis nicht validiert werden kann. Ich verstehe, dass ich etwas falsch mache, aber ich weiß nicht was.

Wie soll ich das Sample mit Bouncy Castle so ändern, dass es mir das gleiche Ergebnis liefert wie der obige Code?

+0

Sie geben nicht die OID bei der Verwendung von CmsSignedDataGenerator, kann dies der Grund sein? –

Antwort

2

Ich fand eine andere discussion, die mir einen Hinweis gab. Es gibt eine Verbindung zu einer GitHub repo mit einer Beispielanwendung. Ich habe es leicht modifiziert und jetzt funktioniert es wie erwartet. Hier ist der Code:

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