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?
InformationsquelleAutor Jean-Paul Berthelot | 2013-06-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin auch auf der Suche an der Oase ebms Zeug.
Ich nicht finden können, den Artikel habe ich diese aus, aber ich habe diese Klasse, die in 4.5:
verwenden und dann so etwas zu Unterschreiben (bearbeitet haben einige irrelevante bits aus):
scheint zu funktionieren und überprüft, OK am anderen Ende. Getestet mit Holodeck den anderen Tag und ich denke, dass es nicht auf einen Zeitstempel, der fehlte noch in der Signatur-Elemente.
Jedoch, die Unterzeichnung der Anlagen zu sein scheint, ein echtes problem .NET - ich glaube nicht, dass die entsprechenden Transformationen werden unterstützt.
cool, ich werde einen Blick zu haben. Dieser Beitrag beschreibt den hack bekommen könnte um es zu lösen cid-Referenzen, obwohl ich sehe immer Referenz zu müssen, sichern Sie die Anlage auf die Festplatte erste, die ich nicht mag den Klang 🙁
Vielleicht war es von social.msdn.microsoft.com/Forums/vstudio/en-US/.... Ich verwendet sehr ähnlichen code, um zu überprüfen, ob eine XML-Signatur SHA-256. Ich glaube, die CryptoConfig.AddAlgorithm () - Methode muss nur einmal aufgerufen werden pro AppDomain - so in Global.asax.cs für eine web-app.
InformationsquelleAutor Andrew
Leider Andrew ' s Antwort ist nicht anwendbar, wenn der private Schlüssel nicht exportiert werden.
Bin ich über eine smart-Karte und so weit ich gefunden habe, keine Möglichkeit, mit SignedXML mit SHA-256. Diese Funktion scheint kaputt zu sein in der aktuellen Implementierung von RSACryptoServiceProvider.
Die einzige Lösung meiner Meinung nach wäre die Umstellung vom CSP, PKCS#11 und dann verwenden BouncyCastle.Net. Und alles umschreiben.
InformationsquelleAutor Jean-François