C# Add wsse:Security and BinarySecurityToken to Envelope xml file programmatically without Web Reference
The BinarySecurityToken is simply the base 64 encoded version of the cert. If you export the cert and copy to file making sure you clicked the Base-64 encoded option you will see the value that is used in the BinarySecurityToken element. You can see this by opening the exported file in notepad.
To programmatically populate your xml element directly from the Client cert do something like this:
var cert = new X509Certificate2(ClientCertificateFilePath, ClientCertificatePassword);
var export = cert.Export(X509ContentType.Cert, ClientCertificatePassword);
var base64 = Convert.ToBase64String(export);
Comments
-
jasilva almost 2 years
Currently I have to generate an XML file, simulating a SOAP request, this file should be signed with an X.509 certificate
At this moment I have this method to sign the file
public static void SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); // Check arguments. if (xmlDoc == null) throw new ArgumentException("xmlDoc"); if (rsaKey == null) throw new ArgumentException("Key"); // Create a SignedXml object. SignedXml signedXml = new SignedXml(xmlDoc); // Add the key to the SignedXml document. signedXml.SigningKey = rsaKey; // Specify a canonicalization method. signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Set the InclusiveNamespacesPrefixList property. XmlDsigExcC14NTransform canMethod = (XmlDsigExcC14NTransform)signedXml.SignedInfo.CanonicalizationMethodObject; canMethod.InclusiveNamespacesPrefixList = "sol soapenv"; // Create a reference to be signed. Reference reference = new Reference(); Reference reference1 = new Reference(); reference.Uri = ""; reference1.Uri = ""; string referenceDigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; reference.DigestMethod = referenceDigestMethod; reference1.DigestMethod = referenceDigestMethod; // Add an enveloped transformation to the reference. //XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); //reference.AddTransform(env); XmlDsigExcC14NTransform c14n = new XmlDsigExcC14NTransform(); c14n.InclusiveNamespacesPrefixList = "wsse sol soapenv"; reference.AddTransform(c14n); XmlDsigExcC14NTransform c14n1 = new XmlDsigExcC14NTransform(); c14n1.InclusiveNamespacesPrefixList = "sol"; reference1.AddTransform(c14n1); // Add the reference to the SignedXml object. signedXml.AddReference(reference); signedXml.AddReference(reference1); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); SecurityTokenReference skr = new SecurityTokenReference(); skr.Reference = "some"; skr.ValueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"; keyInfo.AddClause(skr); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); System.Console.WriteLine(signedXml.GetXml().InnerXml); // Append the element to the XML docu0ment. //xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); XmlElement root = (XmlElement)xmlDoc.GetElementsByTagName("soapenv:Envelope")[0]; string query = string.Format("//*[@Id='{0}']", "IDH"); //Search the Header tag to add signature XmlElement myElement = (XmlElement)xmlDoc.DocumentElement.SelectSingleNode(query); myElement.AppendChild(xmlDigitalSignature); }
I can generate this file
<soapenv:Envelope xmlns:sol=" http://www.sol.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header Id="IDH"> <sol:authentication> <id>4942014103</id> <userid>ME.8494</userid> </sol:authentication> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <InclusiveNamespaces PrefixList="sol soapenv" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/> </CanonicalizationMethod> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <InclusiveNamespaces PrefixList="wsse sol soapenv" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transform> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <DigestValue>BEZBfqQ1QGgbhxvtB83/tr2Yt/8uJPEfvrh8Tn5O6oQ=</DigestValue> </Reference> <Reference URI=""> <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> <InclusiveNamespaces PrefixList="sol" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transform> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <DigestValue>BEZBfqQ1QGgbhxvtB83/tr2Yt/8uJPEfvrh8Tn5O6oQ=</DigestValue> </Reference> </SignedInfo> <SignatureValue>MiOL7D2YfIModsGXh+mm+Ok+oApaYMNenX8xFgwMCXcxW7blHqAPJ2VKGhraAdqy9crAvzEgT6MqD/T9ZWPnK1IHOcQlCt5XICkAlJVnLB78rWkYaTsjNLak2KSvQVCqEDIp0GEwGE6S+5cJykWmbOGiZg50VFFN8QRUlYiIB8I=</SignatureValue> <KeyInfo> <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Reference URI="#some" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/> </wsse:SecurityTokenReference> </KeyInfo> </Signature> </soapenv:Header> <soapenv:Body> <sol:solbus> <in>H4sIAAAAAAAEAI1VXW+bMBR9n7T/YPFcvgJJW9RQUZJ0aAnpAp26vVQWOK2lgCPjJM2/nwEHTEKk8cY59/heHx/Dw+NXtgF7RAtM8rFiaoby6H7/9rBmiTPzYt97X079CeBFeeFWF8FXisfDK2dXT9cDhoB0sj9EMfGIapvy3mUfKJMqjivGAwT5AiVMUajpUdzR2CktRhGHGIrdeQJZAdt/xtbyryBOZJyGc4F1aqUsBnBKCacoGKAn6gaIuSCuQw7+hEKE9x/uGTbAvzYxC684n39+VZuy8fLZpr9p39oPdWSqvEFOZFhhmrCnY5o0d38Vbr+jhJukIJwnuJe41q3QUhicRmYu6LW9lfS2S4FDeaGm/nuWxdY5fOdQ19pmS37e7AS5LSqrrkfCRB/iCbFFGJFHS5jT1Od3DT4ZqwFfIptGku+g+njRq/UoY9Uu9HqjUc3Yk4NfesUxvCDL1/GYblvf/aoYKc1YiqGaYFK0vdhbcKPDCZzsFq6QfLeu2W7lXPoWDjZeR7oRA16NlU+n+MdSXNEtnn3HXbepJtgRdv9RN4v6fh6xR4/CVeTMMYmDdg4oVPr6sN34MjNGSdaVxPvryl/nHFITD+KYYbzNqPloz1SJ4wZZ9BviZA7+ZKvxqsmroWSTmvT3BT/k9AsqO0dGusLN5CRerUWaoT/bN71F6Ymjh9q6S36nngMxEmBLFwcAAA==</in> </sol:solbus> </soapenv:Body> </soapenv:Envelope>
In method SingXml xmlDoc contains this xml, anfter sing I add to header
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sol="http://www.sol.com"> <soapenv:Header Id="IDH"> <sol:authentication> <id></id><userid></userid> <------ With info </sol:authentication> </soapenv:Header> <soapenv:Body> <sol:siatbus> <in></in> <-----With info </sol:siatbus> </soapenv:Body> </soapenv:Envelope>
I need something more, Signature must be within a Security tag inside Header tag, with a BinarySecurityToken element
For example
<soapenv:Header> <!-- extrac of the example file --> <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu=" http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-D53CCD6983E4CE0BD7142791021078262"> MIIDbDgg4iF74cqiF6NcnzBnD9qA2MB6hSo38e0RISilEFSzWikDqBtOjgm7ux9fdeHojDm4uvhsSfbEyGmGTAQRzg9yIiD3ovjOzuZsf+I3HWS9F6xl6sb2+wvYXD4DFk/OD+N7UszGsoWFZg </wsse:BinarySecurityToken> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ..... </ds:Signature>
I can add
<wsse:Security
tag with hard code String, but I do not know if it affects the BinarySecurityToken insideHow is the internal data (
MIIDbDgg4i
....) of the token is generated?What I have to do to add the
Security
tag?Extra
How I can add the prefix
ds
to the Signature and its children?-
Habeeb over 8 yearsDid you already find a solution for this?
-
randomstudious almost 7 yearsTo add the
ds
prefix to the signature and its children: you can add aforeach
loop for allxmlDigitalSignature.ChildNodes
and writechildNode.Prefix = "ds"
inside it, which will assign the prefix to all the child nodes.
-