c# - Signing SOAp Message with XMl Signature and WCF -
currently i'm implementing client in .net consume soap service written in java (i'm not sure). soap envelope has signed in specific way, , has been nightmare trying so.
this example of envelope expecting:
<?xml version="1.0" encoding="utf-8"?> <soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <soapenv:header> <wsse:security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustunderstand="1"> <ds:signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:signedinfo> <ds:canonicalizationmethod algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:canonicalizationmethod> <ds:signaturemethod algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:signaturemethod> <ds:reference uri="#id-319644606"> <ds:transforms> <ds:transform algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:transform> </ds:transforms> <ds:digestmethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:digestmethod> <ds:digestvalue>uqpjnttrxxi7ck9fpeei6yrvhba=</ds:digestvalue> </ds:reference> </ds:signedinfo> <ds:signaturevalue> panzjwyydbntj8ay4z0/wokkquce/z0q/lrcdgb9cp1fn/fzw8uyldashxs2hhlpyg7dafvbtpsq zoiiuszuuubuajjaqlwrzyuecqc48f8x6vxr52mlarnjdpc9mwpzg8ftsoqj2nvyh28chqf8svql kxgtctbil9wpnkzg5m4= </ds:signaturevalue> <ds:keyinfo id="keyid-1827725498"> <wsse:securitytokenreference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:id="strid-131635550"> <ds:x509issuerserial> <ds:x509issuername>cn=desarrollo,ou=ingenieria,o=asobancaria,l=bogota,st=d.c,c=co</ds:x509issuername> <ds:x509serialnumber>1141316577</ds:x509serialnumber> </ds:x509issuerserial> </wsse:securitytokenreference> </ds:keyinfo> </ds:signature> <wsu:timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsu:created>2014-10-29t22:14:01z</wsu:created> <wsu:expires>2014-10-29t22:19:01z</wsu:expires> </wsu:timestamp> </wsse:security> </soapenv:header> <soapenv:body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:id="id-319644606"> <ns1:evaluarcuestionario xmlns:ns1="http://ws.confrontaultra.cifin.asobancaria.com" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"> <p_parametrosseguridad href="#id0"></p_parametrosseguridad> <p_respuestacuestionario href="#id1"></p_respuestacuestionario> </ns1:evaluarcuestionario> <multiref xmlns:ns2="http://ultras.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id1" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:respuestacuestionarioultradto"> <secuenciacuestionario href="#id2"></secuenciacuestionario> <codigocuestionario href="#id3"></codigocuestionario> <respuestas xmlns:ns3="http://ultra.dto.confrontaultra.cifin.co" soapenc:arraytype="ns3:respuestapreguntaultradto[5]" xsi:type="soapenc:array"> <respuestas href="#id4"></respuestas> <respuestas href="#id5"></respuestas> <respuestas href="#id6"></respuestas> <respuestas href="#id7"></respuestas> <respuestas href="#id8"></respuestas> </respuestas> </multiref> <multiref xmlns:ns4="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id0" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns4:parametrosseguridadultradto"> <clavecifin xsi:type="soapenc:string">90681</clavecifin> <password xsi:type="soapenc:string">h32std</password> </multiref> <multiref xmlns:ns5="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id7" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns5:respuestapreguntaultradto"> <secuenciapregunta href="#id9"></secuenciapregunta> <secuenciarespuesta href="#id10"></secuenciarespuesta> </multiref> <multiref xmlns:ns6="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id4" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns6:respuestapreguntaultradto"> <secuenciapregunta href="#id11"></secuenciapregunta> <secuenciarespuesta href="#id12"></secuenciarespuesta> </multiref> <multiref xmlns:ns7="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id6" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns7:respuestapreguntaultradto"> <secuenciapregunta href="#id13"></secuenciapregunta> <secuenciarespuesta href="#id14"></secuenciarespuesta> </multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id2" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:long">8846263</multiref> <multiref xmlns:ns8="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id5" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns8:respuestapreguntaultradto"> <secuenciapregunta href="#id15"></secuenciapregunta> <secuenciarespuesta href="#id16"></secuenciarespuesta> </multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id3" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">7062</multiref> <multiref xmlns:ns9="http://ultra.dto.confrontaultra.cifin.co" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id8" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns9:respuestapreguntaultradto"> <secuenciapregunta href="#id17"></secuenciapregunta> <secuenciarespuesta href="#id18"></secuenciarespuesta> </multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id12" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">150136315</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id14" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">150136266</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id17" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">7</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id10" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">150136259</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id16" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">150136277</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id9" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">20</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id18" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">150136247</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id15" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">35</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id13" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">9</multiref> <multiref xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id11" soapenc:root="0" soapenv:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int">92</multiref> </soapenv:body> </soapenv:envelope>
so have 2 problems:
- i haven't been able set proper namespaces signature header. (the ds namespace)
also, notice wsse:secutirytokenreference tag inside keyinfo tag. signedxml class generates xml default inside keyinfo element:
<keyinfo> <x509data> <x509issuerserial> <x509issuername>cn=rootcatest</x509issuername> <x509serialnumber>228801528337358580231830876343013017805</x509serialnumber> </x509issuerserial> </x509data> </keyinfo>
so, how can replace <x509data>
element <wsse:securitytokenreference>
element.
so far made implementation following lots of posts , blogs i've found in order sign xml document. implementation:
public class signer { public xmldocument signmessage(xmldocument xmldoc, x509certificate2 certificate) { var ns = new xmlnamespacemanager(xmldoc.nametable); ns.addnamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); var body = xmldoc.documentelement.selectsinglenode(@"//soapenv:body", ns) xmlelement; if (body == null) throw new applicationexception("no body tag found"); body.setattribute("id", "body"); var signedxml = new signedxml(xmldoc); var keyinfo = new keyinfo(); signedxml.signingkey = certificate.privatekey; var keyinfodata = new keyinfox509data(); keyinfodata.addissuerserial(certificate.issuer, certificate.getserialnumberstring()); keyinfo.addclause(keyinfodata); signedxml.keyinfo = keyinfo; signedxml.signedinfo.canonicalizationmethod = signedxml.xmldsigexcc14ntransformurl; var reference = new reference { uri = "#body" }; reference.addtransform(new xmldsigexcc14ntransform()); signedxml.addreference(reference); signedxml.computesignature(); var signedelement = signedxml.getxml(); var securitynode = xmldoc.createelement( "wsse", "security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); securitynode.appendchild(signedelement); var timestampnode = xmldoc.createelement("timestamp"); var creatednode = xmldoc.createelement("created"); creatednode.innertext = jsonconvert.serializeobject(datetime.utcnow, new isodatetimeconverter()); var expiresnode = xmldoc.createelement("created"); expiresnode.innertext = jsonconvert.serializeobject(datetime.utcnow.addminutes(5), new isodatetimeconverter()); timestampnode.appendchild(creatednode); timestampnode.appendchild(expiresnode); securitynode.appendchild(timestampnode); var soapheader = xmldoc.documentelement.selectsinglenode(@"//soapenv:header", ns) xmlelement; if (soapheader == null) { soapheader = xmldoc.createelement("soapenv:header", ""); xmldoc.documentelement.insertbefore(soapheader, xmldoc.documentelement.childnodes[0]); } soapheader.appendchild(securitynode); return xmldoc; }
any comments, suggestions, posts, etc helpful. consider have send the envelope require, since organization won't change me, i'm guessing have tons of clients.
thank much!
your approach valid not use wcf security capabilities. recommend first try wcf , if not possible custom signing did. first try wcf binding:
<custombinding> <binding name="newbinding0"> <textmessageencoding messageversion="soap11" /> <security authenticationmode="mutualcertificate" includetimestamp="false" messagesecurityversion="wssecurity10wstrustfebruary2005wssecureconversationfebruary2005wssecuritypolicy11basicsecurityprofile10"> <secureconversationbootstrap /> </security> <httptransport /> </binding> </custombinding>
also configure wcf sign only:
c.endpoint.contract.protectionlevel = system.net.security.protectionlevel.sign;
this create similar soap need keyinfo reference binarysecuritytoken , not in sample. still, suggest try it, there chance work.
if fails need create a code binding , play x509 params. alternatively implement custom wcf encoder change key reference.
i did not followed code. approach sign without wcf valid there chance have errors.
Comments
Post a Comment