Comments (6)
What if you only provide the node to be signed to the signature method? then last child of the node being referenced === the document root. You can then push everything into another root.
Otherwise you can call sig.getSignatureXml() and then insert the signature node yourself to where you want it. The problem might be that putting the signature inside a signed node might invalidate the signed node since its content is now changed. Usually this is done in combination with the enveloped-signature transformation which I don't see in your sample.
from xml-crypto.
Thanks. Signing only the assertion node + using envelope sig transform works. Here's what it looks like:
var SignedXml = require("xml-crypto").SignedXml;
var signingKey = require("fs").readFileSync("./privkey.pem").toString();
var samlAssertion =
"<saml:Assertion Version='2.0'>" +
"<saml:Subject>" +
"<saml:NameID Format='urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'>Test</saml:NameID>" +
"</saml:Subject>" +
"</saml:Assertion>";
var sig = new SignedXml();
sig.addReference("//*[local-name()='Assertion']", ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"]);
sig.signingKey = signingKey;
sig.computeSignature(samlAssertion);
var samlResponse =
"<samlp:Response Version='2.0'>" +
sig.getSignedXml() +
"</samlp:Response>";
console.log(samlResponse);
from xml-crypto.
While that works nicely, I've just noticed that OpenIDP actually signs two nodes in the one XML document...
Example:
<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response Version="2.0" Id="_0">
<saml:Assertion Version="2.0" Id="_1">
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Test</saml:NameID>
</saml:Subject>
<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="#_1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
</Signature>
</saml:Assertion>
<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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
</Signature>
</samlp:Response>
As you can see, both the Response and Assertion nodes have unique Id attributes, and the signatures are nested at different levels. Any recommendations on how to do the same?
Extending my code sample above:
var sig2 = new SignedXml();
sig2.addReference("//*[local-name()='Response']", ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"]);
sig2.signingKey = signingKey;
sig2.computeSignature(samlResponse);
console.log(sig2.getSignedXml());
Outputs the following, which isn't quite correct:
<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response Version="2.0" ID="_0">
<saml:Assertion Version="2.0" ID="_0">
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Test</saml:NameID>
</saml:Subject>
</saml:Assertion>
<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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
</Signature>
</samlp:Response>
from xml-crypto.
what I see in this sample are two different signatures, not one with two referecnes. So you should also create two differenent SignedXml. Assuming the external signature signs the xml without the intrernal signature inside it, first create the external signature and put it inside the root node, and then the internal one.
from xml-crypto.
So if I'm understanding you correctly, something like this?
var SignedXml = require("xml-crypto").SignedXml;
var signingKey = require("fs").readFileSync("./privkey.pem").toString();
var assertion =
"<saml:Assertion Version='2.0'>" +
"<saml:Subject>" +
"<saml:NameID Format='urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'>Test</saml:NameID>" +
"</saml:Subject>" +
"</saml:Assertion>";
var response = "<samlp:Response Version='2.0'>" + assertion + "</samlp:Response>";
var sig1 = new SignedXml();
sig1.addReference("//*[local-name()='Response']", ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"]);
sig1.signingKey = signingKey;
sig1.computeSignature(response);
var sig2 = new SignedXml();
sig2.addReference("//*[local-name()='Assertion']", ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"]);
sig2.signingKey = signingKey;
sig2.computeSignature(sig1.getSignedXml());
console.log(sig2.getSignedXml());
Which outputs this:
<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response Version="2.0" Id="_0">
<saml:Assertion Version="2.0" Id="_0">
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Test</saml:NameID>
</saml:Subject>
</saml:Assertion>
<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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
</Signature>
<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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>...</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>...</SignatureValue>
</Signature>
</samlp:Response>
As you can see, both signatures still reference the same Id. :(
from xml-crypto.
Try to add Id attribute yourself to the SAML elements before signging it (use different values).
from xml-crypto.
Related Issues (20)
- A Proposal for Moving Forward HOT 1
- refactor: deprecate `SignedXml.signingKey` in favor of `SignedXml.publicKey` and `SignedXml.privateKey` HOT 1
- `xpath` dependency "problem" HOT 10
- [ENHANCEMENT]: Signature compliant to http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1 HOT 5
- [ENHANCEMENT]: Export `C14nCanonicalization`, `ExclusiveCanonicalization` HOT 1
- [ENHANCEMENT]: Remove files, folders not needed on the release HOT 2
- Add Reference for the KeyInfo node
- [BUG]: keyInfo usage HOT 4
- invalid signature: for uri calculated digest is '*' but the xml to validate supplies digest '*' HOT 9
- Issue with Signature Verification When 'Transforms' Tag is Absent in 'Reference' Element HOT 5
- How to sign a SAML assertion? HOT 1
- Potentially unsafe default impl for `getKeyInfo()` HOT 2
- [BUG?]: duplicate reference in signature HOT 6
- The declared digest does not match the actual calculated digest HOT 3
- Bug/Outdated README: unclear whether signatureAlgorithm required or not HOT 2
- [ENHANCEMENT]: AddObject to SignedXml instance HOT 4
- [ENHANCEMENT]: wssecurity - getCertFromKeyInfo not possible HOT 1
- [ENHANCEMENT]: Improve experience of adding a `Reference` to the `Signature`.
- [ENHANCEMENT]: Making the signature wrap the content that it's signing HOT 4
- digest is invalid because the computed digest differs from the digest in the XML HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xml-crypto.