Reputation: 4196
I am writing a PHP app (acting as a SAML IdP) which is trying to do a login via a SAML Response to a server (acting as the SAML SP. I am currently stuck with the server rejecting the request (I just get a 500 Bad Request).
I have written a test app (in Java/openSAML - which I'm pretty sure the server is using), and can see that the problem is that the SAML SignatureValidator validate generates
org.apache.xml.security.signature.XMLSignatureException: Invalid XMLDSIG format of DSA signature
Looking at the SAML SignatureValidator code I can see that it checks that the XMLDISG signature is exactly 40 bytes long (P1363 format?) - whereas the generated signature is 46-48 bytes long (DER ASN.1 format?).
The signature is being generated by PHP openssl_sign as below.
openssl_sign($canonicalized_signedinfo,
$signature,
$private_key,
OPENSSL_ALGO_DSS1))
An example signature (displayed as binary to hex for clarity) is as below. This is 46 bytes, but I notice it varies (depending on the random key?) from 46 to 48 bytes.
302c02146e74afeddb0fafa646757d73b43bca688a12ffc5021473dc0ca572352c922b80abd0662965e7b866416d
I can successfully verify this signature using PHP openssl_verify as below.
openssl_verify ($canonicalized_signedinfo,
$signature ,
$public_key,
OPENSSL_ALGO_DSS1))
But in my test app when I do a SignatureValidator validate (as below) I get the XMLSignatureException: Invalid XMLDSIG format of DSA signature
exception.
BasicCredential credential = new BasicCredential();
credential.setPublicKey(publicKey);
credential.setUsageType(UsageType.SIGNING);
SignatureValidator sigValidator = new SignatureValidator(credential);
sigValidator.validate(signature);
Does anyone know how to do the PHP signature conversion from the 46-48 DER ASN.1 format generated by PHP openssl_sign to the 40 byte P1363 format expected by openSAML?
Upvotes: 4
Views: 1704
Reputation: 10381
That resource from code project has explanations about how to convert ASN.1 format into P1363 with code examples. It may be useful to write a Java validation method.
And I propose you use this C++ code to generate a DSIG compliant signature from PHP: http://xmlsig.sourceforge.net/
By the way, it sounds more complex than simply generate the signature and validate it. You may be interested in XMLBlackbox
Upvotes: 3