Coder Social home page Coder Social logo

Comments (7)

yaronn avatar yaronn commented on July 28, 2024

Hi @biofractal

try this sample:

var SignedXml = require('./lib/signed-xml.js').SignedXml
      , fs = require('fs')
      , dom = require('xmldom-fork-fixed').DOMParser
      , select = require('xpath.js')
      , FileKeyInfo = require('./lib/signed-xml.js').FileKeyInfo  

var xml = "<library><book><name>Harry Potter</name></book></library>"
var sig = new SignedXml()
sig.addReference("//*[local-name(.)='library']")    
sig.signingKey = fs.readFileSync("./test/static/client.pem")
sig.computeSignature(xml)
var signed = sig.getSignatureXml()
var withIds = sig.getOriginalXmlWithIds()

var sig = new SignedXml()
sig.keyInfoProvider = new FileKeyInfo("./test/static/client_public.pem")
sig.loadSignature(signed)
var res = sig.checkSignature(withIds)
if (!res) console.log(sig.validationErrors)

if you need a third party to validate this then you need to add an enveloped transformation to code and the validating code should read it and understand it should validate the xml withtout the signature node. Here is how to add a specific tranformation (you can have more then one in the array):

sig.addReference("//*[local-name(.)='root']", ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"], "http://www.w3.org/2000/09/xmldsig#sha1", "", "", "", true)  

from xml-crypto.

biofractal avatar biofractal commented on July 28, 2024

Thanks for the reply.

if you need a third party to validate this then you need to add an enveloped transformation to code
and the validating code should read it and understand it should validate the xml without the signature node. Here is how to add a specific transformation (you can have more then one in the
array):

Right, and there is the problem I think. In reality I am trying to sign a SAML request. This means I am constrained by the SAML schema so I cannot just add a root node and sign the internals. Here is an example of what it should look like:

<?xml version="1.0" encoding="utf-8"?>
<samlp:AuthnRequest Version="2.0" ID="_5FEB2162-F4D0-4900-BC28-F2940188E45B" IssueInstant="2014-10-28T13:07:14.007Z" Destination="https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:Issuer>http://app.localhost9de83841</saml:Issuer>
    <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="#_5FEB2162-F4D0-4900-BC28-F2940188E45B">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <DigestValue>47MSlH9IpJf8vs37T3DnhZMZ7mo=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>T0Uwfmsu...00A==</SignatureValue>
        <KeyInfo>
            <X509Data>
                <X509Certificate>
                    MIIDgDCCAmig ...OgMMxZ
                </X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
    <samlp:NameIDPolicy AllowCreate="true" />
</samlp:AuthnRequest>

You can see that the envelope is the AuthnRequest node. This must be the root node. Also, and this is important, the Signature node comes directly after the Issuer node. Its a real pain I know but if I don't follow the schema then nothing will work.

I managed to get the SAML example above generated by using a hack, I added an xml comment <!-- insert-signature --> at the insertion point then replaced this with the computed signature, like this:

signer = new @xmlcrypto.SignedXml()
signer.signingKey = certificate
signer.addReference "//*[local-name(.)='AuthnRequest']", ['http://www.w3.org/2000/09/xmldsig#enveloped-signature']
signer.keyInfoProvider = new =>
    getKeyInfo: (key)=>
        public_key = /-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g.exec(key)[1]
        "<X509Data><X509Certificate>#{public_key}</X509Certificate></X509Data>"
signer.computeSignature saml
signature = signer.getSignatureXml()
signed = saml.replace '<!-- insert-signature -->', signature

This generated the correct structure but the third party failed to verify the signature, I suspect because the comment was used to compute the digest and then the comment was replaced by the signature.

I would really appreciate any thoughts you might have.

Thanks.

from xml-crypto.

yaronn avatar yaronn commented on July 28, 2024

why do you need the comment? just push the signature as the second child of the root (or do a quick string replace with the previous node hard coded if you just want to test it quickly).

also I suggest you have a sample signed SAML which is know to be working (e.g. a sample from the server) and use the same SAML with same IDs/dates while testing with node. This way you will already be able to see if node generates the expected digest/signature value. Also I suggest at least for start to use a SAML without any white spaces between nodes if possible.

from xml-crypto.

yaronn avatar yaronn commented on July 28, 2024

BTW there are a lot of SAML libraries that already use xml-crypto, see the dependents here:

https://www.npmjs.org/package/xml-crypto

possibly one of them has a sample of this. I believe one of the authors of those libs originally sent the PR with the support for enveloped signatures.

from xml-crypto.

biofractal avatar biofractal commented on July 28, 2024

I used the comment-replacement because it was agnostic to the SAML structure and content, and because it was a quick and dirty hack :-)

I will press on and see how others are achieving this. I really appreciate your suggestions and will implement them.

Thanks

from xml-crypto.

vitalii avatar vitalii commented on July 28, 2024

Hey, biofractal, have you found the solution for your issue? I met the same problem. Can't sign authreq for third part validation. I saw dependants of xml-crypto, but they signed urls instead of root node of xml. I would be grateful for any help.

from xml-crypto.

bjrmatos avatar bjrmatos commented on July 28, 2024

this should be more easy in the last version, please review the docs.

examples are coming..

since this is not a issue.. i'm closing it, feel free to comment if you have any problems

from xml-crypto.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.