2017-12-25 43 views
2

.Net Core(2.0)でPKCS#7分離署名を作成したいと思います。.Net CoreでPKCS#7の分離署名を作成する方法は?

私の質問に多かれ少なかれ関連性の高い質問があり、thisthisの回答が見つかりました。他のすべては無力でした。最初の例は私が必要とするものを正確に行いますが、.NetFrameworkに依存しています。
2番目のものは、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でサンプルを修正すると、上記のコードと同じ結果が得られますか?

+0

CmsSignedDataGeneratorを使用しているときにOidを指定していない場合は、その理由が考えられますか? –

答えて

2

別の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(); 
関連する問題