PHP DSA Signature Conversion from DER ASN.1 to XMLDSIG P1363


PHP DSA Signature Conversion from DER ASN.1 to XMLDSIG P1363

我正在编写一个PHP应用程序(充当SAML IdP),该应用程序试图通过SAML响应登录服务器(充当SAML SP。我目前遇到服务器拒绝请求的问题(我刚刚收到 500 错误请求)。

我已经编写了一个测试应用程序(在Java/openSAML - 我很确定服务器正在使用该应用程序),并且可以看到问题是SAML SignatureValidator validator validator valider生成

org.apache.xml.security.signature.XMLSignatureException: DSA 签名的 XMLDSIG 格式无效

查看 SAML SignatureValidator 代码,我可以看到它检查 XMLDISG 签名的长度是否正好为 40 字节(P1363 格式?),而生成的签名长度为 46-48 字节(DER ASN.1 格式?)。

签名由 PHP openssl_sign生成,如下所示。

openssl_sign($canonicalized_signedinfo,
                  $signature,
                  $private_key,
                  OPENSSL_ALGO_DSS1))

示例签名(为清楚起见,显示为二进制到十六进制)如下所示。这是 46 个字节,但我注意到它从 46 到 48 个字节不等(取决于随机键?

302c02146e74afeddb0fafa646757d73b43bca688a12ffc5021473dc0ca572352c922b80abd0662965e7b866416d

我可以使用PHP openssl_verify成功验证此签名,如下所示。

openssl_verify ($canonicalized_signedinfo, 
                 $signature , 
                 $public_key,
                 OPENSSL_ALGO_DSS1))

但是在我的测试应用程序中,当我进行签名验证器验证(如下所示)时,我得到了XMLSignatureException: Invalid XMLDSIG format of DSA signature异常。

  BasicCredential credential = new BasicCredential();
  credential.setPublicKey(publicKey);
  credential.setUsageType(UsageType.SIGNING);
  SignatureValidator sigValidator = new SignatureValidator(credential);
  sigValidator.validate(signature);

有谁知道如何将PHP签名从PHP openssl_sign生成的46-48 DER ASN.1格式转换为openSAML期望的40字节P1363格式?

代码项目中的该资源通过代码示例解释了如何将 ASN.1 格式转换为 P1363。编写 Java 验证方法可能很有用。

我建议你用这个C++代码从PHP生成一个符合DSIG的签名:http://xmlsig.sourceforge.net/

顺便说一下,这听起来比简单地生成签名并验证它更复杂。您可能对XMLBlackbox感兴趣