I'm using Java8, and I tried both OpenSAML(v3) and OneLogin but none of them worked.
Using this site I tried
Response Signature Inavlid Message looks like this "XMLJS0013: Cryptographic error: Invalid digest for uri '$REFERENCE_URI'. Calculated digest is $CALCULATED_DIGESTVALUE but the xml to validate supplies digest $MY_DIGESTVALUE"
When I manually replace $MY_DIGESTVALUE with $CALCULATED_DIGESTVALUE, the error message changes to "The calculated signature does not match the signature of the message."
/* Methods */
// For OneLogin
private Object stringTOobject(String samlStr) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(samlStr.getBytes("UTF-8")));
Element samlElement = document.getDocumentElement();
Unmarshaller unmarshaller = XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(samlElement);
return unmarshaller.unmarshall(samlElement);
}
// For OpenSAML
private <T> T createObject(Class<T> clazz) throws Exception {
QName defaultElementName = (QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
Object object = SAMLutil.getSAMLBuilder().getBuilder(defaultElementName).buildObject(defaultElementName);
return clazz.cast(object);
}
private KeyInfo getKeyInfo(BasicX509Credential basicCredential, HashMap reqMap) throws Exception {
KeyInfo result = null;
KeyName keyName = createObject(KeyName.class);
keyName.setValue($KeyID);
X509KeyInfoGeneratorFactory kiFactory = new X509KeyInfoGeneratorFactory();
kiFactory.setEmitEntityCertificate(true);
result = kiFactory.newInstance().generate(basicCredential);
result.getKeyNames().add(keyName);
// To remove linebreaks in Certificate
result.getX509Datas().get(0).getX509Certificates().get(0).setValue($X509CertificateString);
return result;
}
private Signature getSig(HashMap reqMap) throws Exception {
Signature result = createObject(Signature.class);
BasicX509Credential basicCredential = getBasicX509Credential($X509CertificateString);
basicCredential.setPrivateKey($PrivateKey);
KeyInfo keyInfo = getKeyInfo(basicCredential, reqMap);
result.setKeyInfo(keyInfo);
result.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
result.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
result.setSigningCredential(basicCredential);
return result;
}
/* OneLogin */
// 1. Sign Assertion > Turn signed string back to Assertion
AssertionMarshaller aMarshaller = new AssertionMarshaller();
String astStr = Util.addSign(aMarshaller.marshall(assertion), privateKey, cert, Constants.RSA_SHA1);
assertion = (Assertion) stringTOobject(astStr);
// 2. Add Assertion into Response
response.getAssertions().add(assertion);
// 3. Sign Response > Turn signed string back to Response
ResponseMarshaller marshaller = new ResponseMarshaller();
String resStr = Util.addSign(marshaller.marshall(response), privateKey, cert, Constants.RSA_SHA1);
response = (Response) stringTOobject(resStr);
// 4. To XMLString
String samlStr = SerializeSupport.nodeToString(marshaller.marshall(response));
/* OpenSAML */
// 1. Sign Assertion
Signature signature = getSig(reqMap);
assertion.setSignature(signature);
((SAMLObjectContentReference)signature.getContentReferences().get(0)).setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA1);
AssertionMarshaller aMarshaller = new AssertionMarshaller();
aMarshaller.marshall(assertion);
Signer.signObject(signature);
// 2. Add Assertion into Response
response.getAssertions().add(assertion);
// 3. Sign Response
Signature signature = getSig(reqMap);
response.setSignature(signature);
((SAMLObjectContentReference)signature.getContentReferences().get(0)).setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA1);
ResponseMarshaller marshaller = new ResponseMarshaller();
marshaller.marshall(response);
Signer.signObject(signature);
// 4. To XMLString
String samlStr = SerializeSupport.nodeToString(marshaller.marshall(response));
What am I missing?
Any help would be really appreciated.
Ok it was the line break in assertion that was making this whole issue. I just replaced the special characters and it magically works so well now.. wow.... The tones of time for nothing... wow.....
astStr = astStr.replace(" ", "").replace("
", "");