I'm facing a strange problem. I'm trying to send a SAMLResponse (SAML 1.1) to an AssertionConsumerService but when validating the signature, he throws this error :
SAMLSignedObject.verify() failed to validate signature value
Apparently there can be 2 reasons to this error :
1) The certificate contained in the <ds:X509Certificate> element is not the same as the one used to sign the assertion.
2) The assertion changed AFTER its signature.
I don't think that the second reason is the right one.
So I want to show you the code I used to create the Credential and the code used to sign. Maybe you will see some mistake I did.
Here the code that creates the Credential :
private BasicX509Credential buildCredential(String keyStorePwd, File keyStoreFile, String entityId, String alias, String password)
throws Exception {
FileInputStream keyStoreFis = new FileInputStream(keyStoreFile);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keyStoreFis, keyStorePwd.toCharArray());
X509Certificate x509Certificate = (java.security.cert.X509Certificate) keyStore.getCertificate(alias);
java.security.Key key = keyStore.getKey(alias, password.toCharArray());
BasicX509Credential credential = new BasicX509Credential();
credential.setEntityCertificate(x509Certificate);
List<X509CRL> crls = new ArrayList<X509CRL>();
credential.setCRLs(crls);
credential.setEntityId(entityId);
credential.setPrivateKey((PrivateKey)key);
credential.setPublicKey(x509Certificate.getPublicKey());
credential.getKeyNames().add(alias);
return credential;
}
And here is the code using this credential to create the signature :
private Signature buildSignature(BasicX509Credential credential,String keyInfoId, String signatureAlgo, String signatureCanonicalAlgo) throws SecurityException, CertificateEncodingException {
Signature signature = samlSignatureBuilder.buildObject();
signature.setSigningCredential(credential);
signature.setSignatureAlgorithm(signatureAlgo);
signature.setCanonicalizationAlgorithm(signatureCanonicalAlgo);
NamedKeyInfoGeneratorManager namedKeyInfoGeneratorManager = securityConfiguration.getKeyInfoGeneratorManager();
KeyInfoGeneratorManager keyInfoGeneratorManager = namedKeyInfoGeneratorManager.getDefaultManager();
KeyInfoGeneratorFactory keyInfoGeneratorFactory = keyInfoGeneratorManager.getFactory(credential);
KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance();
KeyInfo keyInfo = keyInfoGenerator.generate(credential);
signature.setKeyInfo(keyInfo);
return signature;
}
Do you see any error or mistake in that code? I want to assure me that the used certificate for signing is the same that the one in the <ds:X509Certificate>.
Don't hesitate to ask me more informations, if you need.
Thanks in advance!
If you are doing this, the chances are *very* high that the DOM is being
serialized/deserialized in such a way as to mess up the signature. XML
signatures are incredibly brittle in this respect.
--
SWITCH
Serving Swiss Universities
--------------------------
Chad La Joie, Software Engineer, Net Services
Werdstrasse 2, P.O. Box, 8021 Zürich, Switzerland
phone +41 44 268 15 75, fax +41 44 268 15 68
chad....@switch.ch, http://www.switch.ch