C # Поддержка подписи RSA SHA 256 для отдельных элементов XML

Я столкнулся с блокировщиком в .NET Framework версии 4.5 для подписи XML с помощью цифровых подписей.

Моя проблема основана на необходимости подписывать отдельные элементы XML сертификатом X.509 с помощью алгоритма RSA SHA-256. Я прочитал много постов .NET по этой теме, и кажется, что есть решение, изначально разработанное в классе RSRKCS1SHA256SignatureDescription.cs проекта безопасности CLR. RSAPKCS1SHA256SignatureDescription, разумеется, с тех пор был включен в среду выполнения .net, а начиная с .NET 4.5 теперь доступен в распределенном двоичном файле System.Deployment.dll. Я пытался использовать вышеуказанное решение в .NET для подписи определенных элементов XML с помощью RSA SHA-256, однако пока не достиг успеха.

Я пытаюсь подписать сообщение SOAP, соответствующее стандарту Oasis ebms, токеном WSSE. Пожалуйста, имейте в виду, что класс написан для обслуживания Soap With Attachments (SwA) и подписания отдельных вложений. Мой код выглядит следующим образом

Мой код следующий:

using System;
using System.Collections.Generic;
using System.IO;
using System.IdentityModel.Tokens;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Deployment.Internal.CodeSigning;

namespace TestCSharpX509CertificateRSSHA256
{
    public class SignatureSupportUtility
    {

    private bool IsSignatureContentTransform
    {
        get
        {
          return true;
          //get IsSignatureContentTransform                
        }
    }

       public SignatureSupportUtility()
       {
          Register();
       }


    private static void Register()
    {
        CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
    }

    private void Sign(Message message, string[] elementIdsToSign, string[] attachmentsToSign, string wssNamespace, X509Certificate2 certificate)
    {
       //Prepare XML to encrypt and sign
       var element = this.PrepareEncyrptSign(message);

            bool signEntireDocument = true;
            string elementToBeSigned = string.Empty;
            var signedMessage = new XmlDocument();
            signedMessage.AppendChild(signedMessage.ImportNode(element, true));

            SignatureType signAs = SignatureType.InternallyDetached;
            signedMessage.PreserveWhitespace = false;

            OverrideSignedXml signedXml = new OverrideSignedXml(signedMessage);
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

            if (elementIdsToSign != null && elementIdsToSign.Length > 0)
            {
                bool isContentTransform = this.IsSignatureContentTransform;

                foreach (string s in elementIdsToSign)
                {
                    // Create a reference to be signed.
                    Reference reference = new Reference(string.Format("#{0}", s));
                    reference.AddTransform(new XmlDsigExcC14NTransform());
                    reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";


                    // Add the reference to the SignedXml object.
                    signedXml.AddReference(reference);
                }

                signEntireDocument = false;
            }

            // Reference attachments to sign
            if (attachmentsToSign != null && attachmentsToSign.Length > 0)
            {
                bool isContentTransform = this.IsSignatureContentTransform;

                foreach (string attachmentId in attachmentsToSign)
                {
                    // Create a reference to be signed.
                    Reference reference = new Reference(string.Format("{0}{1}", Constants.CidUriScheme, attachmentId));
                    reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

                    if (isContentTransform)
                    {
                        AttachmentContentSignatureTransform env = new AttachmentContentSignatureTransform();
                        reference.AddTransform(env);
                    }
                    else
                    {
                        AttachmentCompleteSignatureTransform env = new AttachmentCompleteSignatureTransform();
                        reference.AddTransform(env);
                    }

                    // Add the reference to the SignedXml object.
                    signedXml.AddReference(reference);
                }

                signEntireDocument = false;
            }

            if (signEntireDocument)
            {
                Reference reference = new Reference();
                reference.Uri = "";
                reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

                XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(env);
                signedXml.AddReference(reference);
                signAs = SignatureType.Enveloped;
            }

            string x509CertificateReferenceId = string.Format("{0}-{1}", Constants.IdAttributeName, Guid.NewGuid().ToString("N"));
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.AddClause(new KeyInfoX509SecurityTokenReference(string.Format("#{0}", x509CertificateReferenceId), wssNamespace));
            signedXml.KeyInfo = keyInfo;
           signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

           RSA  key = (RSACryptoServiceProvider)certificate.PrivateKey;
           signedXML.SigningKey = key;
            CidWebRequest.Message = message;

            signedXml.ComputeSignature();
            var xmlSignature = signedXml.GetXml();
            XmlDocument unsignedEnvelopeDoc = new XmlDocument();
            unsignedEnvelopeDoc.LoadXml(message.MessageAsString); }}} 
using System;
using System.Collections.Generic;
using System.IO;
using System.IdentityModel.Tokens;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Deployment.Internal.CodeSigning;


namespace TestCSharpX509CertificateRSSHA256
{
public sealed class OverrideSignedXml : SignedXml
{
    public OverrideSignedXml()
        : base()
    {
    }

    public OverrideSignedXml(XmlDocument doc)
        : base(doc)
    {
    }

    public override XmlElement GetIdElement(XmlDocument document, string idValue)
    {
        XmlElement element = base.GetIdElement(document, idValue);

        if (element == null)
        {
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
            nsmgr.AddNamespace("wsu", ="http://docs.oasis-open. org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            element = document.SelectSingleNode("//*[@wsu:Id=\"" + idValue + "\"]", nsmgr) as XmlElement;
        }

        return element;
    }
}

}

Метод Sign в моем классе SignatureSupportUtility должен быть достаточным для подписи отдельных элементов XML или всего сообщения, однако я продолжаю получать исключение криптографии, утверждающее, что SHA-256 не поддерживается. Я думаю, что это исключение не должно быть действительным, учитывая, что RSAPKCS1SHA256SignatureDescription.cs зарегистрирован. Однако, учитывая, что класс SignedXML не включает в себя пространство имен для SHA-256 и только SHA-128, я начинаю сомневаться в том, что SHA 256 поддерживается независимо от регистрации.

Может ли кто-нибудь посоветовать мне, как лучше решить мою проблему и как можно подписать XML с помощью сертификата X.509 с помощью алгоритма RSA SHA 256?

Ответы на вопрос(2)

Ваш ответ на вопрос