PHP Saml 2.0,无法验证散列(摘要或签名)
PHP Saml 2.0, not able to validate hashes (Digest or Signature)
我需要你的帮助来找出我在验证散列方面做错了什么。我将代码放在 Gist 中,这样无需滚动即可查看。
这里发送了一个像这样的示例令牌:
https://gist.github.com/NoMan2000/3d3044e8d653a1d580ac#file-saml-xml
我正在尝试检查两个字段,DigestValue 和 SignatureValue。据我了解,DigestValue 是通过查看应用的转换并应用 DigestMethod 中指定的哈希算法来计算的。
该散列是来自原始二进制输出的散列算法的 base64 编码版本。
转换说 "Remove everything in the signature block, convert the string using C14N to canonicalize the output, and calculate the hash based upon the id given in the Reference URI":我基于我在这里阅读的内容:
http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg
然而抓算法,用hash等都不行。我总是没通过那项检查。
https://gist.github.com/NoMan2000/3d3044e8d653a1d580ac#file-samlcontroller-php-L296
同样,每当我尝试验证 SignatureValue 时,我的印象是 SignatureValue 是由 public 密钥使用 SignatureMethod 算法中指定的 SSL 算法加密的 DigestValue。
所以这行代码应该可以工作:
$verify = openssl_verify($digestValue, base64_decode($signatureValue), $pubkeyid, $algo);
但始终验证 returns 0。在我阅读文档时,它是哈希代码的二进制版本加上 public 密钥和算法的字符串。
我已经尝试了几十种显示的代码变体,但从未成功过。有人看到我在这里做错了吗?
您可以尝试使用 LightSAML. Here's an example of signature validation http://www.lightsaml.com/LightSAML-Core/Cookbook/How-to-verify-signature-of-SAML-message/。
反序列化 SAML 响应后,签名验证本身可以像这样完成
// deserialize from XML ...
$response = new \LightSaml\Model\Protocol\Response();
// load IDP certificate
$key = \LightSaml\Credential\KeyHelper::createPublicKey(
\LightSaml\Credential\X509Certificate::fromFile('idp.crt')
);
// validate the signature, will throw an Exception if invalid
$response->getSignature()->validate($key);
我接受了 Milos Tomic 的回答,但使用了 OneLogin。代码几乎相同:
$pubCert = '/path/to/crt/';
$doc = new DOMDocument();
$doc->loadXML($SAMLResponse); // What the server sends over.
$pubkeyid = openssl_x509_read("file://$pubCert");
$validate = OneLogin_Saml2_Utils::validateSign($doc, $pubkeyid);
我需要你的帮助来找出我在验证散列方面做错了什么。我将代码放在 Gist 中,这样无需滚动即可查看。
这里发送了一个像这样的示例令牌:
https://gist.github.com/NoMan2000/3d3044e8d653a1d580ac#file-saml-xml
我正在尝试检查两个字段,DigestValue 和 SignatureValue。据我了解,DigestValue 是通过查看应用的转换并应用 DigestMethod 中指定的哈希算法来计算的。
该散列是来自原始二进制输出的散列算法的 base64 编码版本。
转换说 "Remove everything in the signature block, convert the string using C14N to canonicalize the output, and calculate the hash based upon the id given in the Reference URI":我基于我在这里阅读的内容:
http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg
然而抓算法,用hash等都不行。我总是没通过那项检查。
https://gist.github.com/NoMan2000/3d3044e8d653a1d580ac#file-samlcontroller-php-L296
同样,每当我尝试验证 SignatureValue 时,我的印象是 SignatureValue 是由 public 密钥使用 SignatureMethod 算法中指定的 SSL 算法加密的 DigestValue。
所以这行代码应该可以工作:
$verify = openssl_verify($digestValue, base64_decode($signatureValue), $pubkeyid, $algo);
但始终验证 returns 0。在我阅读文档时,它是哈希代码的二进制版本加上 public 密钥和算法的字符串。
我已经尝试了几十种显示的代码变体,但从未成功过。有人看到我在这里做错了吗?
您可以尝试使用 LightSAML. Here's an example of signature validation http://www.lightsaml.com/LightSAML-Core/Cookbook/How-to-verify-signature-of-SAML-message/。
反序列化 SAML 响应后,签名验证本身可以像这样完成
// deserialize from XML ...
$response = new \LightSaml\Model\Protocol\Response();
// load IDP certificate
$key = \LightSaml\Credential\KeyHelper::createPublicKey(
\LightSaml\Credential\X509Certificate::fromFile('idp.crt')
);
// validate the signature, will throw an Exception if invalid
$response->getSignature()->validate($key);
我接受了 Milos Tomic 的回答,但使用了 OneLogin。代码几乎相同:
$pubCert = '/path/to/crt/';
$doc = new DOMDocument();
$doc->loadXML($SAMLResponse); // What the server sends over.
$pubkeyid = openssl_x509_read("file://$pubCert");
$validate = OneLogin_Saml2_Utils::validateSign($doc, $pubkeyid);