从 DER ASN.1 到 XMLDSIG P1363 的 PHP DSA 签名转换

标签 php openssl saml der xml-dsig

我正在编写一个 PHP 应用程序(充当 SAML IdP),它试图通过对服务器(充当 SAML SP)的 SAML 响应进行登录。我目前被服务器拒绝请求(我只是得到一个 500 Bad Request)。

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

org.apache.xml.security.signature.XMLSignatureException: Invalid XMLDSIG format of DSA signature

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

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

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

示例签名(为清楚起见显示为二进制到十六进制)如下所示。这是 46 个字节,但我注意到它在 46 到 48 个字节之间变化(取决于随 secret 钥?)。

302c02146e74afeddb0fafa646757d73b43bca688a12ffc5021473dc0ca572352c922b80abd0662965e7b866416d

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

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

但是在我的测试应用程序中,当我执行 SignatureValidator 验证时(如下所示),我得到了 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 格式?

最佳答案

那个resource from code project使用代码示例解释了如何将 ASN.1 格式转换为 P1363。编写 Java 验证方法可能会有用。

我建议您使用此 C++ 代码从 PHP 生成符合 DSIG 的签名:http://xmlsig.sourceforge.net/

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

关于从 DER ASN.1 到 XMLDSIG P1363 的 PHP DSA 签名转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11088352/

相关文章:

php - Mysql查询查找不同列的计数

php解析ps aux | grep ...结果

php - 相当于 oppenssl_* 函数中的 hash_hmac

wcf-security - 实现基于声明的安全性 (WCF/ASP.NET)

php - 使用 CodeIgniter 创建 XML

php - 获取 "node reference"的字段或全部内容

ruby - ruby 中的 OpenSSL : PKCS#8 format for private key

ssl - 显示明文密码的 HTTPS header

encryption - 使用 SAML 执行 SSO 时,我可以使用相同的证书进行签名和加密吗?

spring - 为什么我在不使用 RestTemplate 时会收到 SAML 错误?