Hi,<br><br>I'm having a problem with signing my assertion. I did it like shown in the User-Manual and my assertion <br>gets signed (when viewed as text) but the problem is that none of the Service Providers can verify the signature. <br>
So something seems to be wrong but i really can't find the problem so i hope you guys can help me a little.<br><br>Thanks<br><br>Following is some code and the response and metadata files... i hope this is enough to help me.. if something is unclear please ask, i'll then provide the information.<br>
<br>in my programm it is called like this: <br><br>SAML2ApplicationBinding binding = new SAML2ApplicationBinding(app);<br> <br>encoded = binding.getBase64EncodedResponse();<br>samlDocument = binding.getResponseAsString();<br>
<br><br>Here is the code I use to sign the assertion:<br> <br>class SAML2ApplicationBinding {<br> private final String IDP_KEY_FILE = "C:\\Dokumente und Einstellungen\\some_user\\Eigene Dateien\\certs\\idp.der";<br>
private final String IDP_CERT_FILE = "C:\\Dokumente und Einstellungen\\some_user\\Eigene Dateien\\certs\\idp.crt";<br> private SAML2Response response;<br><br> public SAML2ApplicationBinding(Application app) throws NoSuchAlgorithmException, KeyException, SecurityException, MarshallingException, SignatureException, EncryptionException, InvalidKeySpecException, CertificateException, IOException {<br>
application = app;<br><br> this.response = buildSAML2Response();<br> }<br> ....<br> protected SAML2Response buildSAML2Response() throws SecurityException, MarshallingException, SignatureException, NoSuchAlgorithmException, KeyException, EncryptionException, InvalidKeySpecException, CertificateException, IOException {<br>
Assertion assertion = buildSAML2Assertion(getIssuer(), getSubject(), <br> getAudienceRestriction(), getAttributes());<br> response = new SAML2Response(StatusCode.SUCCESS_URI, getIssuer(), assertion);<br>
if (inResponseTo != null) {<br> response.setInResponseTo(inResponseTo);<br> assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData().setInResponseTo(inResponseTo);<br>
}<br> response.signAssertion(getSigningCredentials());<br> <br> if(isEncrypted()) {<br> response.encryptAssertion(getEncryptionCredentials());<br> }<br> <br> return response;<br>
}<br> ...<br> protected Credential getSigningCredentials() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException {<br> // enter files for signing<br> return getCredential(IDP_KEY_FILE, IDP_CERT_FILE);<br>
//BasicX509Credential c = new BasicX509Credential();<br> //c.setPrivateKey(new EncryptionHelper().getPrivateKey(new EncryptionHelper().readKeyFromFile(IDP_KEY_FILE)));<br> //return c;<br> }<br> ....<br>
<br> protected Credential getCredential(String keyFile, String certFile) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException {<br> EncryptionHelper encHelper = new EncryptionHelper();<br>
PrivateKey pk = encHelper.getPrivateKey(encHelper.readKeyFromFile(keyFile));<br> X509Certificate cert = (X509Certificate)encHelper.getCertificate(certFile);<br> <br> BasicX509Credential cred = SecurityHelper.getSimpleCredential(cert, pk);<br>
<br> return cred;<br> }<br> <br> public String getBase64EncodedResponse() {<br> return new String(new Base64().encode(response.toString().getBytes()));<br> }<br>}<br><br>class EncryptionHelper {<br>
public byte[] readKeyFromFile(String privateKeyFile) throws IOException{<br> File privKeyFile = new File(privateKeyFile);<br> BufferedInputStream bs = new BufferedInputStream(new FileInputStream(privKeyFile));<br>
byte[] privKeyBytes = new byte[(int)privKeyFile.length()];<br> bs.read(privKeyBytes);<br> bs.close();<br> return privKeyBytes;<br> }<br> <br> <br> public RSAPrivateKey getPrivateKey(byte[] privKeyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {<br>
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKeyBytes);<br> <br> KeyFactory keyFactory = KeyFactory.getInstance("RSA");<br> return (RSAPrivateKey)keyFactory.generatePrivate(privKeySpec); <br>
}<br>}<br><br>class SAML2Response {<br> ....<br> public void signAssertion(Credential cred) throws SecurityException, MarshallingException, SignatureException {<br> Signature sig = SAMLHelper.createElement(Signature.class, Signature.DEFAULT_ELEMENT_NAME);<br>
sig.setSigningCredential(cred);<br> sig.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);<br> sig.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);<br>
assertion.setSignature(sig);<br> KeyInfoGeneratorFactory kf = Configuration.getGlobalSecurityConfiguration()<br> .getKeyInfoGeneratorManager().getDefaultManager()<br> .getFactory(cred);<br>
KeyInfo ki = kf.newInstance().generate(cred);<br> sig.setKeyInfo(ki);<br> <br> Configuration.getMarshallerFactory().getMarshaller(assertion).marshall(assertion);<br> Signer.signObject(sig);<br>
}<br> ...<br> <br> public String toString() {<br> Element saml;<br> String samlDocument = null;<br> setRightAssertion();<br> try {<br> saml = marshallResponse();<br> samlDocument = XMLHelper.prettyPrintXML(saml);<br>
} catch (MarshallingException e) {<br> e.printStackTrace();<br> }<br> return samlDocument;<br> }<br> <br> protected void setRightAssertion() {<br> if(encryptedAssertion != null) {<br>
setEncryptedAssertionIfNoneIsSet();<br> } else {<br> setAssertionIfNoneIsSet();<br> }<br> }<br> <br> protected void setAssertionIfNoneIsSet() {<br> if(response.getAssertions().size() == 0)<br>
response.getAssertions().add(assertion);<br> }<br> <br>}<br><br>public class SAMLHelper {<br> <br> @SuppressWarnings ("unchecked")<br> public static <T> T createElement(Class<T> cls, QName qname)<br>
{<br> return (T) ((XMLObjectBuilder) Configuration.getBuilderFactory ().getBuilder (qname)).buildObject (qname);<br> }<br>}<br><br><br>The resulting Assertion (samlDocument variable) looks like this when printed<br>
<br><?xml version="1.0" encoding="UTF-8"?><saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" ID="_cd098162-cb16-4c22-92bf-c8a4a2704328" IssueInstant="2012-02-14T15:29:07.353Z" Version="2.0"><br>
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><a href="http://localhost:8080">http://localhost:8080</a></saml2:Issuer><br> <saml2p:Status><br> <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/><br>
</saml2p:Status><br> <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_cd098162-cb66-4c22-92bf-c8a4a2704328" IssueInstant="2012-02-14T15:29:07.275Z" Version="2.0"><br>
<saml2:Issuer><a href="http://localhost:8080">http://localhost:8080</a></saml2:Issuer><br> <ds:Signature xmlns:ds="<a href="http://www.w3.org/2000/09/xmldsig#">http://www.w3.org/2000/09/xmldsig#</a>"><br>
<ds:SignedInfo><br> <ds:CanonicalizationMethod Algorithm="<a href="http://www.w3.org/2001/10/xml-exc-c14n#">http://www.w3.org/2001/10/xml-exc-c14n#</a>"/><br> <ds:SignatureMethod Algorithm="<a href="http://www.w3.org/2000/09/xmldsig#rsa-sha1">http://www.w3.org/2000/09/xmldsig#rsa-sha1</a>"/><br>
<ds:Reference URI="#_cd098162-cb66-4c22-92bf-c8a4a2704328"><br> <ds:Transforms><br> <ds:Transform Algorithm="<a href="http://www.w3.org/2000/09/xmldsig#enveloped-signature">http://www.w3.org/2000/09/xmldsig#enveloped-signature</a>"/><br>
<ds:Transform Algorithm="<a href="http://www.w3.org/2001/10/xml-exc-c14n#">http://www.w3.org/2001/10/xml-exc-c14n#</a>"/><br> </ds:Transforms><br> <ds:DigestMethod Algorithm="<a href="http://www.w3.org/2000/09/xmldsig#sha1">http://www.w3.org/2000/09/xmldsig#sha1</a>"/><br>
<ds:DigestValue>Isy4SHv6cwVl1FpQB2L60lx2n1g=</ds:DigestValue><br> </ds:Reference><br> </ds:SignedInfo><br> <ds:SignatureValue>TBndBsclAvi6pBuZFGO1HEiTxmTxNBXiFQ5Byu3j++jKc8zq+mbujlm0TypTFyBzX7n8DZflIErwkm7w8FBFifkJyzH3+Kkn7URJK5N6BuhJ241WZBBZMnbbdcfI0HOKX7wQSS18ThknUk25vDEOKmnCC762lzaOWXezqiqoP8Wcl+yfDG8eADTf/Ko1WfNIH/4MMC9wOQDuyMz1RogQkPmQqz7kyCNWS1yVRv2m9SZW26/hsIV3/fbEhl0+3/AZJoysvH6oEaTpQoJLjWEpM/wiPtviaT/D3av7iIe2pR/aWFlsWGBkBcEI6AFj+74v2GdgA1QmGLGazo4dt/o2DQ==</ds:SignatureValue><br>
<ds:KeyInfo><br> <ds:X509Data><br> <ds:X509Certificate>MIIDWzCCAkOgAwIBAgIJAPMEpZqGeqqmMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNVBAYTAkRFMQ8w<br>DQYDVQQIDAZCYS1XdWUxEjAQBgNVBAcMCUthcmxzcnVoZTEQMA4GA1UECgwHUG9yc2NoZTAeFw0x<br>
MjAyMTQxNTA1MzlaFw0yMjAyMTMxNTA1MzlaMEQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYS1X<br>dWUxEjAQBgNVBAcMCUthcmxzcnVoZTEQMA4GA1UECgwHUG9yc2NoZTCCASIwDQYJKoZIhvcNAQEB<br>BQADggEPADCCAQoCggEBAOrNmz1j9GyfbhCJ7RdWpeGDumMMGsWHFas9d/3BLA/nAE7OLlf5FHjf<br>
Q5KyCGt98IKEVy3wCyLYw44haBxxJvl1KReuJ4sPZB3L5ahfrr8re6fK6v+znl4oOQY5XMpliRpP<br>e3nTaxVGPWIy28eFFp5xyeXkFWBZqPTVFolW3I4mf0r6HFLMVjndTdJtUqSxWUYdvxseECoYI6bL<br>9sjYEtx9nhB2Po1+RWfTZH5t4fRFcFUr/AVVRncAejgE61aX8IVrMScMZ9iH/eXDbfkGYWG9z3S2<br>
yPgc52naPwfofAgtF/pqXH1Ew5iRhRtYrWRXDNt9owmofLqgGG/oJAUygyMCAwEAAaNQME4wHQYD<br>VR0OBBYEFKuMizdQPCWBXa0IzJ87man5JPD0MB8GA1UdIwQYMBaAFKuMizdQPCWBXa0IzJ87man5<br>JPD0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAI9HPwypM2Uo6Nb51CjwGNVhBegm<br>
KzORuS2pVOMVuUoSSPuR6NRZyIhweLibjaxe40P57KErd22i2YYlIA9jSzo8dTgd/yssrbtTg8c/<br>PthUKaSHujNS4si7CicVcW5pf82F/LocRJ5/2x0pxLXX1DYV3P+ukrY8MgWVOY0z9xWHlvVJCVdw<br>XmHkxV5+DYeoXK62be2uBHzeVyMzxcr4fLd05YpPIUkIcmSg6RG8ZQG/7Mqk734z0jnLN6LJG/cA<br>
eJvI685Uw3nGG+V5EgDcDtitnwaRECgir3Sm1Nn0K+1aKjnOftJpQZfUN8mble7fj24UWg6ZW2VT<br>+KltyImTM1M=</ds:X509Certificate><br> </ds:X509Data><br> </ds:KeyInfo><br> </ds:Signature><br>
<saml2:Subject><br> <saml2:NameID>test_principal</saml2:NameID><br> <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><br> <saml2:SubjectConfirmationData NotBefore="2012-02-14T15:29:07.338Z"/><br>
</saml2:SubjectConfirmation><br> </saml2:Subject><br> <saml2:Conditions><br> <saml2:AudienceRestriction><br> <saml2:Audience>saml2SP</saml2:Audience><br>
</saml2:AudienceRestriction><br> </saml2:Conditions><br> <saml2:AuthnStatement AuthnInstant="2012-02-14T15:29:07.338Z"><br> <saml2:AuthnContext><br> <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef><br>
</saml2:AuthnContext><br> </saml2:AuthnStatement><br> <saml2:AttributeStatement><br> <saml2:Attribute Name="Nachname"><br> <saml2:AttributeValue>lastname</saml2:AttributeValue><br>
</saml2:Attribute><br> <saml2:Attribute Name="Abteilung"><br> <saml2:AttributeValue>unit</saml2:AttributeValue><br> </saml2:Attribute><br> <saml2:Attribute Name="Firma"><br>
<saml2:AttributeValue>company</saml2:AttributeValue><br> </saml2:Attribute><br> <saml2:Attribute Name="Vorname"><br> <saml2:AttributeValue>firstname</saml2:AttributeValue><br>
</saml2:Attribute><br> </saml2:AttributeStatement><br> </saml2:Assertion><br></saml2p:Response><br><br>So the signature seems to be there.... but when checked at the other side (oracle weblogic / simplesamlphp) the certificate in the metadata seem not to <br>
match the signature or the signature does not match the document... i'm not 100% sure at this point. But what's for sure is that it does not work ;-)<br><br>The Metadata I'm using is like this:<br><?xml version="1.0"?><br>
<md:EntityDescriptor<br> xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"<br> xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"<br> xmlns:ds="<a href="http://www.w3.org/2000/09/xmldsig#">http://www.w3.org/2000/09/xmldsig#</a>"<br>
entityID="<a href="http://localhost:8080">http://localhost:8080</a>"><br> <md:IDPSSODescriptor<br> protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><br> <md:KeyDescriptor use="signing"><br>
<ds:KeyInfo xmlns:ds="<a href="http://www.w3.org/2000/09/xmldsig#">http://www.w3.org/2000/09/xmldsig#</a>"><br> <ds:X509Data><br> <ds:X509Certificate><br>MIIDWzCCAkOgAwIBAgIJAPMEpZqGeqqmMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV<br>
BAYTAkRFMQ8wDQYDVQQIDAZCYS1XdWUxEjAQBgNVBAcMCUthcmxzcnVoZTEQMA4G<br>A1UECgwHUG9yc2NoZTAeFw0xMjAyMTQxNTA1MzlaFw0yMjAyMTMxNTA1MzlaMEQx<br>CzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYS1XdWUxEjAQBgNVBAcMCUthcmxzcnVo<br>ZTEQMA4GA1UECgwHUG9yc2NoZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC<br>
ggEBAOrNmz1j9GyfbhCJ7RdWpeGDumMMGsWHFas9d/3BLA/nAE7OLlf5FHjfQ5Ky<br>CGt98IKEVy3wCyLYw44haBxxJvl1KReuJ4sPZB3L5ahfrr8re6fK6v+znl4oOQY5<br>XMpliRpPe3nTaxVGPWIy28eFFp5xyeXkFWBZqPTVFolW3I4mf0r6HFLMVjndTdJt<br>UqSxWUYdvxseECoYI6bL9sjYEtx9nhB2Po1+RWfTZH5t4fRFcFUr/AVVRncAejgE<br>
61aX8IVrMScMZ9iH/eXDbfkGYWG9z3S2yPgc52naPwfofAgtF/pqXH1Ew5iRhRtY<br>rWRXDNt9owmofLqgGG/oJAUygyMCAwEAAaNQME4wHQYDVR0OBBYEFKuMizdQPCWB<br>Xa0IzJ87man5JPD0MB8GA1UdIwQYMBaAFKuMizdQPCWBXa0IzJ87man5JPD0MAwG<br>A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAI9HPwypM2Uo6Nb51CjwGNVh<br>
BegmKzORuS2pVOMVuUoSSPuR6NRZyIhweLibjaxe40P57KErd22i2YYlIA9jSzo8<br>dTgd/yssrbtTg8c/PthUKaSHujNS4si7CicVcW5pf82F/LocRJ5/2x0pxLXX1DYV<br>3P+ukrY8MgWVOY0z9xWHlvVJCVdwXmHkxV5+DYeoXK62be2uBHzeVyMzxcr4fLd0<br>5YpPIUkIcmSg6RG8ZQG/7Mqk734z0jnLN6LJG/cAeJvI685Uw3nGG+V5EgDcDtit<br>
nwaRECgir3Sm1Nn0K+1aKjnOftJpQZfUN8mble7fj24UWg6ZW2VT+KltyImTM1M=<br> </ds:X509Certificate><br> </ds:X509Data><br> </ds:KeyInfo><br> </md:KeyDescriptor><br> <md:NameIDFormat><br>
urn:oasis:names:tc:SAML:2.0:nameid-format:transient<br> </md:NameIDFormat><br> <md:SingleSignOnService<br> Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"<br>
Location="<a href="http://localhost:8080/testSaml/getTestSaml">http://localhost:8080/testSaml/getTestSaml</a>"/><br> </md:IDPSSODescriptor><br> <md:Organization><br> <md:OrganizationName xml:lang="en"><br>
SAML2 Demo Provider<br> </md:OrganizationName><br> <md:OrganizationDisplayName xml:lang="en"><br> SAML2 Demo Identity Provider @ localhost<br> </md:OrganizationDisplayName><br>
<md:OrganizationURL xml:lang="en"><br> <a href="http://localhost:8080">http://localhost:8080</a><br> </md:OrganizationURL><br> </md:Organization><br> <md:ContactPerson contactType="technical"><br>
<md:SurName>some-lastname</md:SurName><br> <md:EmailAddress><a href="mailto:some@email.de">some@email.de</a></md:EmailAddress><br> </md:ContactPerson><br> </md:EntityDescriptor><br>