2017-12-25 37 views
2

.Net Core (2.0)로 PKCS # 7 분리 서명을 만들고 싶습니다..Net Core를 사용하여 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으로 샘플을 수정해야 위 코드와 동일한 결과를 얻을 수 있습니까?

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