Skip to Content.
Sympa Menu

mace-opensaml-users - Re: signature validation in OpenSAML2

Subject: OpenSAML user discussion

List archive

Re: signature validation in OpenSAML2


Chronological Thread 
  • From: Kenny Pearce <>
  • To:
  • Subject: Re: signature validation in OpenSAML2
  • Date: Tue, 11 Dec 2007 08:45:26 -0500
  • Organization: Hx Technologies

Well, I did SOAPMessage.writeTo(), saved the output, and ran diff on
them, and diff said they were the same. I think that's a bit-for-bit
comparison. Do you have any idea how to do a more precise comparison, or
whether there might be some other problem?

On Tue, 2007-12-11 at 08:02 +0100, Chad La Joie wrote:
> I wouldn't be surprised if your SOAP container is changing the message
> in some fashion. Axis, at least at one point, had a nasty habit of
> screwing with namespace prefixs before it sent out a message, this then
> invalidated any signature that it didn't control. Such problems tend to
> be very difficult to detect.
>
> Kenny Pearce wrote:
> > I am able to validate the signature on the client side, and I've
> > verified that the message looks the same on the client side and on the
> > server side, when printed out from java using SOAPMessage.writeTo(). I
> > set the rootLogger to DEBUG, and got tons of output, most of which
> > doesn't mean anything to me, but this part looked like it might be
> > relevant:
> >
> > ----------------
> > 2007-12-10 15:50:35.725 DEBUG - Attempting to validate signature using
> > key from supplied credential
> > 2007-12-10 15:50:35.729 DEBUG - Creating XMLSignature object
> > 2007-12-10 15:50:35.729 DEBUG - verify 1 References
> > 2007-12-10 15:50:35.734 DEBUG - I am not requested to follow nested
> > Manifests
> > 2007-12-10 15:50:35.734 DEBUG - setElement("ds:Reference", "")
> > 2007-12-10 15:50:35.734 DEBUG - setElement("ds:Transforms", "")
> > 2007-12-10 15:50:35.735 DEBUG - Request for URI
> > http://www.w3.org/2000/09/xmldsig#sha1
> > 2007-12-10 15:50:35.735 DEBUG - I was asked to create a ResourceResolver
> > and got 0
> > 2007-12-10 15:50:35.735 DEBUG - extra resolvers to my existing 4
> > system-wide resolvers
> > 2007-12-10 15:50:35.735 DEBUG - check resolvability by class
> > org.apache.xml.security.utils.resolver.implementations.ResolverFragment
> > 2007-12-10 15:50:35.735 DEBUG - State I can resolve reference:
> > "#pg4R25EQ0Xvj.tCuFMTsb"
> > 2007-12-10 15:50:35.735 DEBUG - getElementByIdType() Search for ID
> > pg4R25EQ0Xvj.tCuFMTsb
> > 2007-12-10 15:50:35.735 DEBUG - getElementByIdUsingDOM() Search for ID
> > pg4R25EQ0Xvj.tCuFMTsb
> > 2007-12-10 15:50:35.735 DEBUG - I could find an Element using the simple
> > getElementByIdUsingDOM method: saml:Assertion
> > 2007-12-10 15:50:35.736 DEBUG - Try to catch an Element with ID
> > pg4R25EQ0Xvj.tCuFMTsb and Element was [saml:Assertion: null]
> > 2007-12-10 15:50:35.736 DEBUG - setElement("ds:Transform", "")
> > 2007-12-10 15:50:35.736 DEBUG - Preform the (0)th
> > http://www.w3.org/2000/09/xmldsig#enveloped-signature transform
> > 2007-12-10 15:50:35.736 DEBUG - setElement("ds:Transform", "")
> > 2007-12-10 15:50:35.736 DEBUG - setElement("ec:InclusiveNamespaces", "")
> > 2007-12-10 15:50:35.737 INFO - Verification successful for URI
> > "#pg4R25EQ0Xvj.tCuFMTsb"
> > 2007-12-10 15:50:35.737 DEBUG - The Reference has Type
> > 2007-12-10 15:50:35.737 DEBUG - SignatureMethodURI =
> > http://www.w3.org/2000/09/xmldsig#rsa-sha1
> > 2007-12-10 15:50:35.737 DEBUG - Create URI
> > "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; class "class
> > org.apache.xml.security.algorithms.implementations.SignatureBaseRSA
> > $SignatureRSASHA1"
> > 2007-12-10 15:50:35.737 DEBUG - Request for URI
> > http://www.w3.org/2000/09/xmldsig#rsa-sha1
> > 2007-12-10 15:50:35.737 DEBUG - Created SignatureDSA using SHA1withRSA
> > 2007-12-10 15:50:35.737 DEBUG - jceSigAlgorithm = SHA1withRSA
> > 2007-12-10 15:50:35.737 DEBUG - jceSigProvider = SunRsaSign
> > 2007-12-10 15:50:35.738 DEBUG - PublicKey = Sun RSA public key, 512 bits
> > modulus:
> > 11917871527246057771552089994960395089648245713568677534401387968986688360812296227814709715932744936657696959516727964652299195519294629634916966166224953
> > public exponent: 65537
> > 2007-12-10 15:50:35.739 DEBUG - Signature did not validate against the
> > credential's key
> > ----------------
> >
> > None of this looks like an explanation of the validation failure to me.
> > Any ideas? Is there something else I should be looking for in the rest
> > of the output?
> >
> > Thanks.
> >
> > On Fri, 2007-12-07 at 13:57 -0500, Brent Putman wrote:
> >> Hi Kenny,
> >> What you're doing there looks functionally correct, no obvious problems
> >> that I can see. No, you don't need to do anything to the Credential in
> >> order to validate, all that's needed within the Credential for the
> >> signing and validation operations are the key(s).
> >>
> >> So the obvious observation would be, assuming that you're seeing it fail
> >> in an actual client/server exchange, is that the document really is
> >> getting changed somehow in transit, and that's breaking the signature.
> >> So this is a SAML token attached within a WS-Security header? For
> >> example, something in the serialization on the client and/or
> >> deserialization and unmarshalling process on the server, could be
> >> changing whitespace, namespaces, etc. Have you tried running the same
> >> signing and validation code inside a single JVM process (unit test or
> >> whatever) one immediately after the other, to see if that is
> >> succeeding? If so, then that's your answer.
> >>
> >> On the server (validation) side, it might be helpful to get a log trace
> >> on DEBUG minimally from packages org.opensaml.xml.security,
> >> org.opensaml.xml.signature and in particular org.apache.xml.security.
> >> The Apache lib is what is actually doing the validation operation. That
> >> should provide more details on exactly why it is failing.
> >>
> >> Some other observations, not directly related to your problem:
> >> The entityId member on the credential is intended to be the owning
> >> entity ID of the Credential's key. The getID from the SAML object is
> >> the Assertion ID or Request/Response message ID. Those are 2 totally
> >> different things, so you shouldn't be calling Credential#setEntityId
> >> like that. But like I said, you don't need to set the entityID on the
> >> Credential at all, it's not relevant here.
> >>
> >> FYI, there's a utility method
> >> org.opensaml.xml.security.SecurityHelper#getSimpleCredential that can
> >> build the credential with the key(s) if you already have keys and just
> >> need a Credential. Ordinarily we resolve Credentials from a
> >> CredentialResolver, though.
> >>
> >> For your production code KeyInfo handling, you may want to take a look
> >> at the KeyInfoCredentialResolver so that you don't hardcode assumptions
> >> about what kind of keys are being used (i.e. might have an
> >> X509Data/X509Certificate rather than a KeyValue).
> >>
> >> Also be aware that this approach doesn't in any way handle establishing
> >> that you trust the key used by the signer. If you are not otherwise
> >> handling that outside of what you illustrate here, you might want to
> >> take a look at the SignatureTrustEngine impls we have, which both
> >> cryptographically validate the Signature as you're doing here as well as
> >> establish trust of the signing key based on various approaches (known
> >> trusted credentials and PKIX).
> >>
> >> --Brent
> >>
> >>
> >>
> >> Kenny Pearce wrote:
> >>> Hi again,
> >>> I've written a (relatively) simple test application, for trying to use
> >>> OpenSAML2 in WSS with JAX-WS. To simplify things, I tried just having
> >>> the client generate a KeyPair and put the public key in the KeyInfo
> >>> element, so that the server could pull it out and use it to validate the
> >>> signature. I've verified that the public key the server is pulling out
> >>> matches the one the client is putting in, but the signature is being
> >>> reported as invalid. I'm signing like this:
> >>>
> >>>
> >>> -----------------------
> >>> Signature sig =
> >>> ((XMLObjectBuilder<Signature>)buildFact.getBuilder(Signature.DEFAULT_ELEMENT_NAME)).buildObject(Signature.DEFAULT_ELEMENT_NAME);
> >>>
> >>> BasicCredential cred = new BasicCredential();
> >>> cred.setEntityId(saml.getID());
> >>>
> >>> cred.setPrivateKey(keys.getPrivate());
> >>> cred.setPublicKey(keys.getPublic());
> >>>
> >>> sig.setSigningCredential(cred);
> >>> sig.setSignatureAlgorithm(RSA_ALG);
> >>>
> >>> sig.setCanonicalizationAlgorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315";);
> >>>
> >>> KeyInfo inf =
> >>> ((XMLObjectBuilder<KeyInfo>)buildFact.getBuilder(KeyInfo.DEFAULT_ELEMENT_NAME)).buildObject(KeyInfo.DEFAULT_ELEMENT_NAME);
> >>> KeyInfoHelper.addPublicKey(inf, keys.getPublic());
> >>>
> >>> sig.setKeyInfo(inf);
> >>>
> >>> saml.setSignature(sig);
> >>>
> >>> [snip]
> >>>
> >>> Element elem =
> >>> Configuration.getMarshallerFactory().getMarshaller(saml).marshall(saml);
> >>> Signer.signObject(saml.getSignature());
> >>> -----------------------
> >>>
> >>>
> >>> And I'm validating like this:
> >>>
> >>> -----------------------
> >>> BasicCredential cred = new BasicCredential();
> >>> try{
> >>> cred.setPublicKey(KeyInfoHelper.getKey(saml.getSignature().getKeyInfo().getKeyValues().get(0)));
> >>> }catch(Exception e){
> >>> throw new ValidationException("Could not get public
> >>> key", e);
> >>> }
> >>> cred.setEntityId(saml.getID());
> >>> SignatureValidator sigval = new SignatureValidator(cred);
> >>> sigval.validate(saml.getSignature());
> >>> -----------------------
> >>>
> >>> The very last line of the snippet above throws a ValidationException
> >>> saying that the signature is invalid. Am I doing something wrong? Do I
> >>> need to set more fields of the BasicCredential before I can validate?
> >>>
> >>> Thanks,
> >>>
> >>>
>




Archive powered by MHonArc 2.6.16.

Top of Page