C# - Unterstützung für RSA-SHA-256-Signatur für einzelne XML-Elemente

Dem ich begegnet bin, einen blocker mit .NET Framework version 4.5 zu tun mit der Unterzeichnung von XML-Daten mit digitalen Signaturen.

Mein problem ist, basierend auf der anmelden, die einzelnen XML-Elemente mit einem X. 509-Zertifikat mit der RSA-SHA-256-Algorithmus. Ich habe gelesen, dass viele .NET Beiträge zu diesem Thema und es scheint, dass es eine Lösung entwickelt, die ursprünglich in der CLR Security project RSAPKCS1SHA256SignatureDescription.cs-Klasse. RSAPKCS1SHA256SignatureDescription natürlich hat sich da schon eingearbeitet .net-runtime und der .NET 4.5 ist ab sofort unter der binäre verteilt System.Deployment.dll. Ich habe versucht, die obige Lösung .NET sign-spezifische XML-Elemente mit RSA-SHA-256 haben jedoch noch keinen Erfolg.

Ich versuche zu Zeichen einer SOAP-Nachricht, die Einhaltung der Oase ebms mit einem standard-WSSE-Token. Bitte beachten Sie, dass die Klasse geschrieben ist, für zu sorgen Soap With Attachments (SwA) und die Unterzeichnung der einzelnen Anlagen.
Mein code ist wie folgt

Mein code ist der folgende:

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;
    }
}

}

Zeichen-Methode in meinem SignatureSupportUtility-Klasse sollte ausreichend sein, um die Zeichen einzelne XML-Elemente oder die ganze Meldung, aber ich bekomme immer wieder eine Kryptographie Ausnahme zu fordern, dass die SHA-256 nicht unterstützt. Ich denke, dass diese Ausnahme nicht gelten beobachten, dass die RSAPKCS1SHA256SignatureDescription.cs registriert. Jedoch die Beobachtung, dass die SignedXML-Klasse nicht enthalten ist der namespace für SHA-256 und nur SHA-128 beginne ich zu zweifeln, ob die SHA-256 unterstützt, unabhängig von Ihrer Registrierung.

Könnte jemand bitte raten Sie mir, wie Sie am besten zu lösen mein Problem und in der Lage sein, zu unterzeichnen, XML mit einem X. 509 Zertifikat über RSA-SHA-256-Algorithmus?

Wenn Sie nicht eingeschränkt sind .NET Framework-Klassen, können Sie versuchen, XML-Signierung Funktionalität in unserem SecureBlackbox Produkt, da es bietet viel mehr Funktionalität. Siehe eldos.com/sbb/net-xml.php

InformationsquelleAutor Jean-Paul Berthelot | 2013-06-23

Schreibe einen Kommentar