OpenSAML Signing

Phil Lello phil at dunlop-lello.uk
Fri Nov 6 11:25:27 EST 2015


I now have this working; there were two things to change:

- The signing code now looks like:

                Signature signature =
(Signature)Configuration.getBuilderFactory().getBuilder(Signature.
DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);
                signature.setSigningCredential(credential);
                SecurityConfiguration securityConfiguration =
Configuration.getGlobalSecurityConfiguration();
                SecurityHelper.prepareSignatureParams(signature,
credential, securityConfiguration, null);
                r.setSignature(signature);

Configuration.getMarshallerFactory().getMarshaller(r).marshall(r);
                Signer.signObject(signature);

This correctly adds the DS:X509 section to the generated XML

- Adding metadata for the SP to the IdP (I haven't written my Metadata
export yet, but had expected signed requests to be treated the same way as
unsigned ones at the IdP, rather than throwing (IMHO) a misleading
"org.opensaml.messaging.handler.MessageHandlerException: Validation of
protocol message signature failed" when the message is intact but the IdP
lacks metadata.

Everything now looks good, although I'm not convinced that there aren't
higher level functions I should be using.

Phil

On Fri, Nov 6, 2015 at 12:26 PM, Phil Lello <phil at dunlop-lello.uk> wrote:

> Hi all,
>
> I've been trying to write an SP implementation, first with core Java, and
> now with OpenSAML after I hit a roadblock. Unfortunately, I'm getting stuck
> in the same place; I can sign assertions, but the signatures are invalid.
>
> My current code is as follows:
>
>                 AuthnRequestBuilder rb = new AuthnRequestBuilder();
>                 AuthnRequest r = rb.buildObject();
>                 IssuerBuilder ib = new IssuerBuilder();
>                 Issuer i = ib.buildObject();
>                 i.setValue(this.url);
>                 r.setIssuer(i);
>                 r.setIssueInstant(new DateTime());
>                 r.setID(generateId());
>                 r.setAssertionConsumerServiceURL(url+"sp/acs");
>                 r.setDestination(IdP);
>
> r.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
>                 NameIDPolicyBuilder nb = new NameIDPolicyBuilder();
>                 NameIDPolicy nameIDPolicy = nb.buildObject();
>                 nameIDPolicy.setAllowCreate(true);
>
> nameIDPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
>                 r.setNameIDPolicy(nameIDPolicy);
>
>                 BasicX509Credential credential = new BasicX509Credential();
>                 JcaPEMKeyConverter kc = new
> JcaPEMKeyConverter().setProvider("BC");
>                 credential.setEntityCertificate(getCertificate());
>
> credential.setPrivateKey(kc.getPrivateKey(getPrivateKeyInfo()));
>                 KeyInfoGeneratorFactory kigf = new
> X509KeyInfoGeneratorFactory();
>                 KeyInfo ki = kigf.newInstance().generate(credential);
>
>                 Signature signature =
> (Signature)Configuration.getBuilderFactory().getBuilder(Signature.
> DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);
>                 signature.setSigningCredential(credential);
>
> signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
>
> signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
>                 signature.setKeyInfo(ki);
>                 r.setSignature(signature);
>
> Configuration.getMarshallerFactory().getMarshaller(r).marshall(r);
>                 Signer.signObject(signature);
>
>                 MarshallerFactory mf =
> Configuration.getMarshallerFactory();
>                 Marshaller m = mf.getMarshaller(r);
>
>                 DOMSource source = new DOMSource(m.marshall(r));
>                 TransformerFactory tf = TransformerFactory.newInstance();
>                 Transformer t = tf.newTransformer();
>                 StringWriter sw = new StringWriter();
>                 StreamResult result = new StreamResult(sw);
>                 t.transform(source, result);
>                 byte[] encodedBytes =
> Base64.encodeBase64(sw.toString().getBytes());
>
> And the certificate/key reading functions are:
>
>     protected X509Certificate getCertificate() throws IOException,
> CertificateException
>     {
>         Path x509crtfile = dataDir.resolve("cert.pem");
>         PEMParser pem = new PEMParser(Files.newBufferedReader(x509crtfile,
> Charset.forName("UTF8")));
>         return new
> JcaX509CertificateConverter().setProvider("BC").getCertificate((X509CertificateHolder)pem.
> readObject());
>     }
>
>     protected PrivateKeyInfo getPrivateKeyInfo() throws IOException,
> NoSuchAlgorithmException,                InvalidKeySpecException
>     {
>
>         Path x509keyfile = dataDir.resolve("key.pem");
>         Security.addProvider(new BouncyCastleProvider());
>         PEMParser pem = new PEMParser(Files.newBufferedReader(x509keyfile,
> Charset.forName("UTF8")));
>         return (PrivateKeyInfo)pem.readObject();
>     }
>
> Any pointers on where I'm going wrong, or perhaps a reference to a working
> signed AuthnRequest example greatly appreciated.
>
> The cert/key were generated by "openssl req -x509 -newkey rsa:2048 -keyout
> key.pem -out cert.pem -days 3650 -nodes"; I can share the files if it will
> help.
>
> Phil
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/dev/attachments/20151106/f4469a26/attachment-0001.html>


More information about the dev mailing list