540 likes | 1.13k Views
XML Security. September 13, 2006 Robert Richards rrichards@php.net. Digital Signatures and Encryption. Canonicalization A standard form of data Digital Signatures Provides proof of identity and authenticity which the sender cannot deny. Encryption
E N D
XML Security September 13, 2006 Robert Richards rrichards@php.net
Digital Signatures and Encryption • Canonicalization • A standard form of data • Digital Signatures • Provides proof of identity and authenticity which the sender cannot deny. • Encryption • Protection of data from being accessed by unauthorized parties.
Existing Tools/Technologies • Secure Sockets Layer (SSL) • Transport Layer Security (TLS) • Pretty Good Privacy (PGP) • GNU Privacy Guard (GnuPG) • OpenPGP • S/MIME • x.509
XML Security Standards • Canonical XML http://www.w3.org/TR/xml-c14n/ • Exclusive XML Canonicalization http://www.w3.org/TR/xml-exc-c14n/ • XML Signature http://www.w3.org/TR/xmldsig-core/ • XML Encryption http://www.w3.org/TR/xmlenc-core/ • XML Key Management http://www.w3.org/TR/xkms2/
XML Security in PHP • A library based on the xmlsec library is currently in the works • http://www.aleksey.com/xmlsec/ • Provides granular control for working with XML Digital Signatures and XML Encryption • PHP based libraries are available • Model libraries for designing xmlsec wrapper • Not officially mainitained and may not be backwards compatible with xmlsec based extension • Requires PHP 5.1+ (5.2 is recommended) • Requires DOM, OpenSSL and Mcrypt • http://www.cdatazone.org/files/xmlseclibs.phps • http://www.cdatazone.org/files/soap-wsse.phps • http://www.cdatazone.org/files/ws-amazon.phps • http://www.cdatazone.org/infocard/infocard-lib.phps • http://www.cdatazone.org/infocard/infocard.phps
Benefits of XML Security Standards • XML is a structured format • Allows for secure storage of documents • Leverages existing technologies • Provides granularity
XML Canonicalization A standard serialization of an XML document or XPath node set <data a="1" b="2" c="3"/> <data b="2" c="3" a="1"/> <data c="3" a="1" b="2"></data> <data c="3" a="1" b="2"></data> <data a="1" b="2" c="3"></data>
Canonical XML (C14N) http://www.w3.org/TR/2001/REC-xml-c14n-20010315 http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments • XML declaration and DTD are removed • The document is encoded in UTF-8 • Line breaks normalized to #xA (linefeed) on input, before parsing • Empty elements are converted to start-end tag pairs • Whitespace outside of the document element and within start and end tags is normalized • Attribute value delimiters are set to double quotes • Superfluous namespace declarations are removed from each element • Lexicographic order is imposed on the namespace declarations and attributes of each element
Canonical XML Example #1 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <!-- Comment --> <doc> <e1 a:attr='out' b:attr='sorted' attr2='all' attr="I'm" xmlns:b='http://www.ietf.org' xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </e2> </doc> Canonical Form of Document (uncommented) <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <doc> <e1 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e1> <e2 xmlns:a="http://www.w3.org"> <e3></e3> </e2> </doc>
Canonical XML Example #1 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <!-- Comment --> <doc> <e1 a:attr='out' b:attr='sorted' attr2='all' attr="I'm" xmlns:b='http://www.ietf.org' xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </e2> </doc> Canonical Form of Document (uncommented) <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <doc> <e1 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e1> <e2 xmlns:a="http://www.w3.org"> <e3></e3> </e2> </doc>
Canonical XML Example #1 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <!-- Comment --> <doc> <e1 a:attr='out' b:attr='sorted' attr2='all' attr="I'm" xmlns:b='http://www.ietf.org' xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </e2> </doc> Canonical Form of Document (uncommented) <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <doc> <e1 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e1> <e2 xmlns:a="http://www.w3.org"> <e3></e3> </e2> </doc>
Canonical XML Example #1 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <!-- Comment --> <doc> <e1 a:attr='out' b:attr='sorted' attr2='all' attr="I'm" xmlns:b='http://www.ietf.org' xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </e2> </doc> Canonical Form of Document (uncommented) <?xml-stylesheet href="doc.xsl" type="text/xsl" ?> <doc> <e1 xmlns="http://example.org" xmlns:a="http://www.w3.org" xmlns:b="http://www.ietf.org" attr="I'm" attr2="all" b:attr="sorted" a:attr="out"></e1> <e2 xmlns:a="http://www.w3.org"> <e3></e3> </e2> </doc>
Canonical XML Example #2 <?xml version="1.0" encoding="UTF-8"?> <doc xmlns:d="http://www.example.org/d" xmlns:c="http://www.example.org/c"> <e1 a:attr="out" b:attr="sorted" attr2="all" attr="I'm" xmlns:b="http://www.ietf.org" xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <d:e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </d:e2> </doc> Canonical Form of Nodeset (uncommented) (//. | //@* | //namespace::*)[ancestor-or-self::d:e2] <d:e2 xmlns:a="http://www.w3.org" xmlns:c="http://www.example.org/c" xmlns:d="http://www.example.org/d"> <e3></e3> </d:e2>
Canonical XML Example #2 <?xml version="1.0" encoding="UTF-8"?> <doc xmlns:d="http://www.example.org/d" xmlns:c="http://www.example.org/c"> <e1 a:attr="out" b:attr="sorted" attr2="all" attr="I'm" xmlns:b="http://www.ietf.org" xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <d:e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </d:e2> </doc> Canonical Form of Nodeset (uncommented) (//. | //@* | //namespace::*)[ancestor-or-self::d:e2] <d:e2 xmlns:a="http://www.w3.org" xmlns:c="http://www.example.org/c" xmlns:d="http://www.example.org/d"> <e3></e3> </d:e2>
Canonical XML Example #2 <?xml version="1.0" encoding="UTF-8"?> <doc xmlns:d="http://www.example.org/d" xmlns:c="http://www.example.org/c"> <e1 a:attr="out" b:attr="sorted" attr2="all" attr="I'm" xmlns:b="http://www.ietf.org" xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <d:e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </d:e2> </doc> Canonical Form of Nodeset (uncommented) (//. | //@* | //namespace::*)[ancestor-or-self::d:e2] <d:e2 xmlns:a="http://www.w3.org" xmlns:c="http://www.example.org/c" xmlns:d="http://www.example.org/d"> <e3></e3> </d:e2>
Problem with Re-Enveloping <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> <!-- Document wrapped within ns0:e1 element --> <ns0:e1 xmlns:ns0="www.example.org/ns0"> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> </ns0:e1> <!-- Canonical Form --> <d:e2 xmlns:d="http://www.example.org/d" xmlns:ns0="www.example.org/ns0">content</d:e2> <!-- Document wrapped within ns1:e1 element --> <ns1:e1 xmlns:ns0="www.example.org/ns1"> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> </ns1:e1> <!-- Canonical Form --> <d:e2 xmlns:d="http://www.example.org/d" xmlns:ns1="www.example.org/ns1">content</d:e2>
Exclusive XML Canonicalization http://www.w3.org/2001/10/xml-exc-c14n# http://www.w3.org/2001/10/xml-exc-c14n#WithComments • Follows the same rules as Canonical XML, except… • Attributes in the xml namespace are not imported into orphan nodes • Namespaces not specially told to be added are only added on the starting element for which they are visible and not currently in scope within the output.
Re-Enveloping using Exclusive <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> <!-- Document wrapped within ns0:e1 element --> <ns0:e1 xmlns:ns0="www.example.org/ns0"> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> </ns0:e1> <!-- Canonical Form --> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> <!-- Document wrapped within ns1:e1 element --> <ns1:e1 xmlns:ns0="www.example.org/ns1"> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2> </ns1:e1> <!-- Canonical Form --> <d:e2 xmlns:d="http://www.example.org/d">content</d:e2>
Exclusive Canonical XML Example <?xml version="1.0" encoding="UTF-8"?> <doc xmlns:d="http://www.example.org/d" xmlns:c="http://www.example.org/c"> <e1 a:attr="out" b:attr="sorted" attr2="all" attr="I'm" xmlns:b="http://www.ietf.org" xmlns:a="http://www.w3.org" xmlns="http://example.org"/> <d:e2 xmlns="" xmlns:a="http://www.w3.org"> <e3 xmlns="" xmlns:a="http://www.w3.org"/> </d:e2> </doc> Exclusive Canonical Form of Nodeset (uncommented) (//. | //@* | //namespace::*)[ancestor-or-self::d:e2] <d:e2 xmlns:d="http://www.example.org/d"> <e3></e3> </d:e2>
XML Digital Signature (XMLDSIG) • Insure that a message has not been altered or tampered with. (integrity) • Protection against attacks that alter a message but maintain integrity. (message authentication) • Provide a means for message auditing so that messages may not be repudiated. (signer authenticity)
XML Signature Structure xmlns="http://www.w3.org/2000/09/xmldsig#" <Signature> <SignedInfo> <CanonicalizationMethod/> <SignatureMethod/> (<Reference URI? > (<Transforms>)? <DigestMethod> <DigestValue> </Reference>)+ </SignedInfo> <SignatureValue> (<KeyInfo>)? (<Object Id?>)* </Signature>
XML Signature: Types of Signatures • Enveloping Signature • Data lives within the XML Signature structure • Good for signing data being packaged within an XML payload • Enveloped Signature • Data lives outside of and contains the XML Signature structure • Good for signing portions or all of an XML document • Detached Signature • Data lives outside and DOES NOT contain the XML Signature structure • Data may reside at a remote location addressable by URI
Enveloping Signature <?xml version="1.0"?> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/> <Reference URI="#myobj"> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>C2g9BLcGyGPCVKuF2byR1Ym+6pE=</DigestValue> </Reference> </SignedInfo> <SignatureValue>+R/XEOHDvR/jbmmpiuH4ZcRqC6c=</SignatureValue> <Object Id="myobj">Hello World!</Object> </Signature>
Enveloped Signature <?xml version="1.0"?> <Envelope> <Data>content</Data> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/> <Reference> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>MMMkB0ZPp82XrUvJMFqDIEuXy0o=</DigestValue> </Reference> </SignedInfo> <SignatureValue>mVPvfcVSXi9elKL+IcSCAzD4Jbk=</SignatureValue> </Signature></Envelope>
Detached Signature <?xml version="1.0"?> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/> <Reference URI="http://www.ctindustries.net/text.txt"> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>oLZZOWcLwsAQ9NXWoLPk5FkPuSs=</DigestValue> </Reference> </SignedInfo> <SignatureValue>O9ykpFMXmkddzJ3CySrpzHBUW/Q=</SignatureValue> </Signature>
XML Signature Generation • Apply any transforms to the data • Calculate the digest value • Create the Reference Element • Repeat steps 1 – 3 for each piece of data to be included • Create SignedInfo element with SignatureMethod, CanonicalizationMethod and Reference elements • Canonicalize the SignedInfo element • Calculate the SignatureValue over the canonicalized SignedInfo based the SignatureMethod • Assemble the Signature element
SOAP Request <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.csapi.org/schema/parlayx/terminal_location/v2_0/local" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:getLocation> <address>tel:1234567890</address> <requestedAccuracy xsi:type="xsd:int">xx</requestedAccuracy> <acceptableAccuracy xsi:type="xsd:int">yy</acceptableAccuracy> </ns1:getLocation> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAP Request: WS-Security (Signature) <soapenv:Envelope ...> <soapenv:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/. . ." soapenv:mustunderstand="1"> <wsse:BinarySecurityToken . . .>MIIE3zCCBEigAwIBAg . . .</wsse:BinarySecurityToken> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:Reference URI="#9b6c55bc-558f-e61a-e99a-ee2084f22000">. . .</ds:Reference> <ds:Reference URI="#c359df59-9262-d587-18af-add2c0dc1ddb">. . .</ds:Reference> </ds:SignedInfo> <ds:SignatureValue>Yd1TGIjOb3q4UcQkUBuM3Q6Zs3G...</ds:SignatureValue> <ds:KeyInfo>. . .</ds:KeyInfo> </ds:Signature> <wsu:Timestamp xmlns:wsu="http:// ."wsu:Id="9b6c55bc-558f-e61a-e99a-ee2084f22000"> </wsse:Security> </soapenv:Header> <soapenv:Body xmlns:wsu="http://. . ." wsu:Id="c359df59-9262-d587-18af-add2c0dc1ddb">
SOAP Request: WS-Security Generation require('soap-wsse.php'); define('PRIVATE_KEY', 'private_key.pem'); define('CERT_FILE', 'cert.pem'); class mySoap extends SoapClient { public function __doRequest($request, $location, $saction, $version) { $doc = new DOMDocument('1.0'); $doc->loadXML($request); /* WS-Security Specific code here */ return parent::__doRequest($wsseRequest, $location, $saction, $version); } }
SOAP Request: WS-Security Generation $objWSSE = new WSSESoap($doc->loadXML($request)); /* add Timestamp with default expiration timestamp */ $objWSSE->addTimestamp(); /* $objWSSE->addUserToken('username', 'password', TRUE); */ /* create new XMLSec Key using RSA SHA-1 and type is private key */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private')); /* load private key from file - last arg is bool if key in file (TRUE) or is string (FALSE) */ $objKey->loadKey(PRIVATE_KEY, TRUE); /* Sign the message - also signs appropraite WS-Security items */ $objWSSE->signSoapDoc($objKey); /* Add certificate (BinarySecurityToken) to the message and attach pointer to Signature */ $token = $objWSSE->addBinaryToken(file_get_contents(CERT_FILE)); $objWSSE->attachTokentoSig($token); $wsseRequest = $objWSSE->saveXML();
SOAP Request: signSoapDoc() $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $arNodes = array(); /* $this->secNode refers to wsse:Security node within tree */ foreach ($this->secNode->childNodes AS $node) { if ($node->nodeType == XML_ELEMENT_NODE) $arNodes[] = $node; } foreach ($this->envelope->childNodes AS $node) { if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') { $arNodes[] = $node; break; } } $arOptions = array('prefix'=>WSSESoap::WSUPFX, 'prefix_ns'=>WSSESoap::WSUNS); $objDSig->addReferenceList($arNodes, XMLSecurityDSig::SHA1, NULL, $arOptions); $objDSig->sign($objKey); $objDSig->appendSignature($this->secNode, TRUE);
XML Signature Validation • Obtain the verification keying information • Apply the CanonicalizationMethod to the SignedInfo element • Verify the SignatureValue using the canonical form of the SignatureMethod • For each Reference element within SignedInfo: • Obtain the data to be digested • Digest the data using the DigestMethod within its Referece element • Compare the computed value to that of the un-encoded value from the DigestValue element
XML Encryption (XMLENC) • Encrypted data is maintained. • All information needed to decrypt a document is contained within the document. • Session can be secured on the document level and shared between multiple parties. • Sensitive data is easily interchanged between applications.
XML Encryption Structure xmlns:enc="http://www.w3.org/2001/04/xmlenc#" <enc:EncryptedData Id? Type? MimeType?> <enc:EncryptionMethod Algorithm />? <dsig:KeyInfo>? <enc:CipherData> <enc:CipherValue>? <enc:CipherReference URI?>? </enc:CipherData> <enc:EncryptionProperties>? </enc:EncryptedData>
XML Encryption: Encrypting • Select the algorithm (and parameters) to use in encrypting the item. • Obtain the key and create ds:KeyInfo if necessary • Encrypt the data and prepend any appropriate initialization vector (IV). • Build CipherData element • If to be stored within CipherValue element, then encrypted data is base64 encoded. • If encrypted data is external, then create CipherReference with URI and any transforms. • Build EncryptedData or EncryptedKey structure
XML Encryption Example <payment> <order_number>1001</order_number> <customer>Joe Smith</customer> <creditcard> <number>4111 1111 1111 1111</number> <expiration_month>01</expiration_month> <expiration_year>2007</expiration_year> <ccv2>123</ccv2> </creditcard> </payment>
XML Encryption ExampleElement / Shared Secret Key <?xml version="1.0"?> <payment> <order_number>1001</order_number> <customer>Joe Smith</customer> <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <CipherData> <CipherValue>C5X1I65RCX…</CipherValue> </CipherData> </EncryptedData> </payment>
XML Encryption Example: Code require('xmlseclibs.php'); /* Using a shared secret key for encryption */ $key = 'secret'; $doc = new DOMDocument(); $xpath = new DOMXPath($doc ->load('payment.xml')); $creditcard = $xpath->query("//creditcard")->item(0); $enc = new XMLSecEnc(); $enc->setNode($creditcard); $enc->type = XMLSecEnc::Element; /* Use the libraries to encrypt the credit card element within the document */ $objKey = new XMLSecurityKey(XMLSecurityKey::TRIPLEDES_CBC); $objKey->loadKey($key); $encNode = $enc->encryptNode($objKey); print $encNode->ownerDocument->saveXML();
XML Encryption ExampleElement Content / Shared Secret Key <?xml version="1.0"?> <payment> <order_number>1001</order_number> <customer>Joe Smith</customer> <creditcard><EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Content"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <CipherData> <CipherValue>C5X1I65RCX…</CipherValue> </CipherData> </EncryptedData></creditcard> </payment>
XML Encryption ExampleArbitrary Data with Shared Secret Key <?xml version='1.0'?> <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#' xmlns:ds='http://www.w3.org/2000/09/xmldsig#' MimeType='text/xml'> <CipherData> <CipherValue>...C5X1I65RCX...</CipherValue> </CipherData> </EncryptedData>
XML Encryption: Decrypting • Determine encryption algorithm and parameters. • Obtain the decryption key information. • Obtain the data to decrypt. • If CipherData has a CipherValue child then base-64 decode its contents. • If CipherData has a CipherReference child, retrieve the data and apply any Transforms. • Depending upon algorithm and parameters, strip any IV from the data to use for decryption. • Decrypt the cipher data with the encryption algorithm, parameters, and keying material.
XML Encryption: Decrypting Example (Infocard) <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"> <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#"> <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> </e:EncryptionMethod> <KeyInfo> <o:SecurityTokenReference xmlns:o="…/oasis-200401-wss-wssecurity-secext-1.0.xsd"> . . .</o:SecurityTokenReference> </KeyInfo> <e:CipherData> <e:CipherValue>kXja26CSDKssMeqJcsJttLg…</e:CipherValue> </e:CipherData> </e:EncryptedKey> </KeyInfo> <CipherData><CipherValue>eIreM+S35Q+=…</CipherValue></CipherData> </EncryptedData>
XML Encryption: Code (Infocard) require('xmlseclibs.php'); define('PRIVATE_KEY', 'site_sslprivate.key'); define('SAML_ASSERT_NS', 'urn:oasis:names:tc:SAML:1.0:assertion'); $encdom = new DOMDocument(); $encdom->loadXML($xmlToken); $objenc = new XMLSecEnc(); $encData = $objenc->locateEncryptedData($encdom); if (! $encData) { throw new Exception("Cannot locate Encrypted Data"); } $objenc->setNode($encData); $objenc->type = $encData->getAttribute("Type");
XML Encryption: Code (Infocard) $key = NULL; $objKey = $objenc->locateKey(); if ($objKey) if ($objKeyInfo = $objenc->locateKeyInfo($objKey)) if ($objKeyInfo->isEncrypted) { $objencKey = $objKeyInfo->encryptedCtx; $objKeyInfo->loadKey(PRIVATE_KEY, TRUE); $key = $objencKey->decryptKey($objKeyInfo); } if (empty($objKey) || empty($key)) throw new Exception("Error loading key to handle Decryption"); $objKey->loadKey($key); $token = NULL; if ($decrypt = $objenc->decryptNode($objKey, FALSE)) { $token = new DOMDocument(); $token->loadXML($decrypt); }
XML Encryption: Code (Infocard) <saml:Assertion ... AssertionID="uuid:17818733-c534-42d9-a6f6-4bb1c32d0de7"> <!-- SAML related information --> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#uuid:17818733-c534-42d9-a6f6-4bb1c32d0de7"> <Transforms> . . . </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>eHLrK4QSEkrDhHXZYHgGJMkPAU4=</DigestValue> </Reference> </SignedInfo> <SignatureValue>0uDR9pr/TusV...</SignatureValue> <KeyInfo><KeyValue> <RSAKeyValue> <Modulus>8llAGAvlPuG...</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue></KeyInfo> </Signature>
XML Encryption: Code (Infocard) /* Validate the SAML token */ $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys[] = 'AssertionID'; $objDSig = $objXMLSecDSig->locateSignature($token); /* Canonicalize the signed info */ $objXMLSecDSig->canonicalizeSignedInfo(); $retVal = NULL; if ($objDSig) { $retVal = $objXMLSecDSig->validateReference(); } if (! $retVal) { throw new Exception("SAML Validation Failed"); } $objKey = $objXMLSecDSig->locateKey(); /* Additional Key handling here */ if (empty($objKey)) throw new Exception("Error loading key to handle Signature"); if (! $objXMLSecDSig->verify($objKey)) throw new Exception("Unable to validate Signature");
Signing and Encrypting • Sign and then Encrypt • Provides signature protection • Allows for encryption algorithm to be changed without affecting signature • Incurs additional overhead as you must decrypt before you can verify • Encrypt and then Sign • Immediately know if data has been tampered with • Document can no longer be shared with other parties without revealing decryption key • Sender identity is revealed
XML Encryption in WS-Security <env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <env:Header> <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"> <xenc:ReferenceList> <xenc:DataReference URI="#encryptedID"/> </xenc:ReferenceList> </wsse:Security> </env:Header> <env:Body> <xenc:EncryptedData Id="encryptedID"> <xenc:CipherData> <xenc:CipherValue>...</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </env:Body> </env:Envelope>