Digitally Sign a SAML2 Request in NodeJS

好久不见. 提交于 2020-01-01 12:16:12

问题


I have the following SAML request that I want to digitally sign:

<samlp:AuthnRequest Version="2.0" ID="_9FE393FB-1C9C-4EDD-86A5-1AE9F2192A60" IssueInstant="2014-10-22T11:22:56.676Z" Destination="https://idp.ssocircle.com:443/sso/SSOPOST/metaAlias/ssocircle" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml:Issuer>http://app.localhost</saml:Issuer>
    <samlp:NameIDPolicy AllowCreate="true" />
</samlp:AuthnRequest>

I use the following coffeescript code which relies on the nodejs xmlbuilder and xmlcrypto modules:

request = @xmlbuilder.create
    'samlp:AuthnRequest':
        '@xmlns:samlp':'urn:oasis:names:tc:SAML:2.0:protocol'
        '@xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion'
        '@Version': '2.0'
        '@ID': requestId
        '@IssueInstant': (new Date()).toISOString()
        '@Destination': idpUrl
        'saml:Issuer': '@@spEntityId'
    ,null
    ,headless: true

request.comment 'insert-signature-here'
request.element 'samlp:NameIDPolicy':
                    '@AllowCreate': 'true'
saml = request.end()

@fs.readFile "certs/my-cert.pem", (err, certificate)=>
    return next @errorService.readFileError certFilePath, err if err?
    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].replace /[\r\n|\n]/g, ''
            "<X509Data><X509Certificate>#{public_key}</X509Certificate></X509Data>"
    signer.computeSignature saml
    signature = signer.getSignatureXml()
    signed = saml.replace '<!-- insert-signature-here -->', signature
    console.log signed

Which generates the following digitally signed SAML request:

<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>T0Uw...KZkm00A==</SignatureValue>
        <KeyInfo>
            <X509Data>
                <X509Certificate>MIIDg...OgMMxZ</X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
    <samlp:NameIDPolicy AllowCreate="true" />
</samlp:AuthnRequest>

This appears to be valid.

However when I test this with SSOCircle and TestShib they both report that the digest value does not match.

The certificate I am using is a self-signed certificate (pem) with an unencrypted private key.

I have double checked to categorically ensure that the public key supplied in the sp-metadata was taken from the same pem file used to digitally sign the SAML.

Does the private key need to be encrypted?

If not then can you suggest why the signature check should fail?

Thanks.


回答1:


Private key should not be encrypted. You can use this online tool https://www.samltool.com/validate_logout_req.php validating your signature. If it does not pass means your signature created in a wrong way



来源:https://stackoverflow.com/questions/26506822/digitally-sign-a-saml2-request-in-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!