Question about verifying signatureValue for SAML2 redirect initiated by Shibboleth SP
Maassen, Helma
helma.maassen at atos.net
Fri Feb 7 07:34:36 EST 2014
hi,
Sorry in advance for this long post.......
I have the following issue;
I'm using Shibboleth SP 2.5.1. to start a session.
So the SP generates a AuthnRequest, and sends it to the configured IDP.
This is done by sending a GET request to the IDP url:
https://idp.net/broker/sso/1.5?SAMLRequest=fVPBbuIwEL3vV0S%2B..........dkqoARc%2B90gdKL3TUJ%2FcXmS76D254qN8q57%2FeOV%2F&RelayState=ss%3Amem%3A2a145986d479c5694e3e4a101422d756fa75361700b557bb4aca7b6bfe1660d5&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1
&Signature=MUuiVGl8X0w74jG...........9732NWviy6FdPOBugDX%2BtF2iySz7g5XIb3wUE6QMAC6bbijf16hEIx1nhghg2hHGI3aKVCwq8maGmS5BwFl3f85GPBT0R9ouCA%3D%3D
AFAIK the IDP should be able to verify the Signature, using the Public Key we did share.
Now I get to the real problem; The IDP I'm trying to connect to, does actually perform such a Signature verification, but it FAILS!
So what I tried, is to perform the verification myself, using a small Java program (source below).
I've based my program on the functionality SAML2RedirectEncoder.cpp, I find that the Signature is calculated over the complete string "SAMLRequest=.....&RelayState=......&SigAlg=......"
So I need to verify the Signature value to that string.
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
public class TestURLEncoded2 {
public static String signedValue = "SAMLRequest=fVPBbuIwEL3vV0S%2Bkzihoa1FIrFwW.....76D254qN8q57%2FeOV%2F&RelayState=ss%3Amem%3A2a145986d479c5694e......56fa75361700b557bb4aca7b6bfe1660d5&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1";
public static String signatureValue = "Signature=MUuiVGl8X0w74jGghui23XKyuSiYXeogvV..........3aKVCwq8maGmS5BwFl3f85GPBT0R9ouCA%3D%3D";
public static void main(String[] args) throws GeneralSecurityException, IOException {
TestURLEncoded2 test = new TestURLEncoded2();
String signatureValueDecoded = test.urlDecode(signatureValue);
byte[] signedValueInBytes = test.base64Decode(signedValue);
byte[] signatureValueInBytes = test.base64Decode(signatureValueDecoded);
PublicKey pubKey = getPublicKeyFromPem(retrievePEMCertificate());
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(pubKey);
byte[] sigToVerify = signatureValueInBytes;
sig.update(signedValueInBytes);
try {
if (sig.verify(sigToVerify)) {
System.out.println("SUCCES!!!");
} else {
System.out.println("Something wrong");
}
} catch (SignatureException e) {
e.printStackTrace();
}
}
private String urlDecode(String stringValue) throws UnsupportedEncodingException {
return URLDecoder.decode(stringValue, "UTF-8");
}
private byte[] base64Decode(String stringValue) {
return Base64.decodeBase64(stringValue);
}
.....
}
When I feed the program with the Shibboleth-SP created request, it seems to fail.
When I feed the program with a self constructed and signed request, it works fine, so the part of reading and loading the certificate seems to be working fine.
=======>> Can anyone find the flaw in my program? (Did I use the correct classes?)
Eventually;
I need to find out how to convince the IDP-guys (so how to prove), that the Signature value in the request sent is valid for the content from the request.
or
I need to find a way to improve my SP config so Signature verification will succeed :-(
Best regards!
Helma Maassen.
More information about the users
mailing list