2012-08-01 37 views
7

Tôi đang sử dụng phương pháp dưới đây để ký tài liệu XML:Ký một tài liệu XML sử dụng RSA-SHA256 phương pháp chữ ký vấn đề

public static XmlDocument SignDocument(XmlDocument doc) 
    { 
     string signatureCanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#"; 
     string signatureMethod = @"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; 
     string digestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256"; 

     string signatureReferenceURI = "#_73e63a41-156d-4fda-a26c-8d79dcade713"; 

     CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), signatureMethod); 

     var signingCertificate = GetCertificate(); 

     SignedXml signer = new SignedXml(doc); 
     signer.SigningKey = signingCertificate.PrivateKey; 
     signer.KeyInfo = new KeyInfo(); 
     signer.KeyInfo.AddClause(new KeyInfoX509Data(signingCertificate)); 

     signer.SignedInfo.CanonicalizationMethod = signatureCanonicalizationMethod; 
     signer.SignedInfo.SignatureMethod = signatureMethod; 

     XmlDsigEnvelopedSignatureTransform envelopeTransform = new XmlDsigEnvelopedSignatureTransform(); 
     XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform(); 

     Reference signatureReference = new Reference(); 
     signatureReference.Uri = signatureReferenceURI; 
     signatureReference.AddTransform(envelopeTransform); 
     signatureReference.AddTransform(cn14Transform); 
     signatureReference.DigestMethod = digestMethod; 

     signer.AddReference(signatureReference); 

     signer.ComputeSignature(); 
     XmlElement signatureElement = signer.GetXml(); 

     doc.DocumentElement.AppendChild(signer.GetXml()); 

     return doc; 
    } 


     private static X509Certificate2 GetCertificate() 
    { 

     X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     store.Open(OpenFlags.ReadOnly); 
     X509Certificate2 card = null; 
     foreach (X509Certificate2 cert in store.Certificates) 
     { 
      if (!cert.HasPrivateKey) continue; 

      if (cert.Thumbprint.Equals("a_certain_thumb_print", StringComparison.OrdinalIgnoreCase)) 
      { 
       card = cert; 
       break; 
      } 
     } 
     store.Close(); 

     return card; 
    } 

Một ngoại lệ của loại System.Security.Cryptography.CryptographicException được ném khi cố gắng tính toán chữ ký với thông báo lỗi Thuật toán không hợp lệ được chỉ định. Bất kỳ ý tưởng?

Máy: Windows Server 2008 R2

.Net Framework: 4.0.

IDE: Visual Studio 2010.

+4

tôi giải quyết vấn đề này (nhờ Phillip) như sau: /* thêm dòng mã sau đây sau var signingCertificate = GetCertificate(); */ CspParameters cspParams = CspParameters mới (24); cspParams.KeyContainerName = "XML_DISG_RSA_KEY"; Khóa RSACryptoServiceProvider = RSACryptoServiceProvider mới (cspParams); key.FromXmlString (signingCertificate.PrivateKey.ToXmlString (true)); /* chỉ định khóa mới cho phím SigningKey */ metadataSigner.SigningKey = của người ký; – UncleZen

+0

thx UncleZen đã sửa nó nhưng cspParams.KeyContainerName = "XML_DISG_RSA_KEY" không cần thiết nó cũng hoạt động mà không có nó. – BitSchupser

Trả lời

2

Cảm ơn bạn rất nhiều vì blog này. Nó thực sự giải quyết vấn đề của tôi. Nhân tiện, nếu chứng chỉ được tải từ tệp, bạn có thể xuất chứng chỉ: X509Certificate2 x509Key = new X509Certificate2 ("xxxxx.pfx", "123", X509KeyStorageFlags.Exportable);

+0

Điều này không trả lời câu hỏi –

+4

Điều đó không trả lời câu hỏi, nhưng sau khi triển khai giải pháp của Bác, bạn sẽ gặp lỗi "Khóa không hợp lệ để sử dụng ở trạng thái được chỉ định" nếu khóa không được gắn cờ là có thể xuất. – BitSchupser

1

Trả lời từ @minhj đề cập đến một số blog, nhưng liên kết không có ở đó.

Tuy nhiên, thêm lớp được đề cập here và đăng ký nó đã khắc phục được sự cố. Dường như nó chỉ được đăng ký một lần cho mỗi miền ứng dụng.

Các vấn đề liên quan