我是SSL证书的新手。对到目前为止我所做的事情有些谨慎。
我正在创建一个使用SSO来使用PHP 5.4验证用户身份的应用程序。
我有的:
一方提供的证书(.pfx)。
POST变量中的加密SAML。

解密后的xml与SAML: Why is the certificate within the Signature?几乎相似

我需要验证响应是否来自经过验证的提供程序。。我在四处搜寻时需要知道.pem而不是.pfx,因此我已经使用ssl命令将.pfx文件转换为.pem。我已经使用了http://www.php.net/manual/es/function.openssl-verify.php#62526的代码。这是我的代码。

$encxml=$_POST['SAMLResponse'];
$xml = new SimpleXMLElement(base64_decode($encxml));
$signature = ((string)$xml->Signature->SignatureValue);
var_dump($signature);


//do I need to do something with this X509Certificate value embedded in xml??
$cert = ((string)$xml->Signature->KeyInfo->X509Data->X509Certificate);
var_dump($cert);

//Or I need
$fp = fopen("xyz.pem", "r");
$priv_key = fread($fp, 8192);
fclose($fp);
print_r($priv_key);
$ok = openssl_verify($xml, $signature, $priv_key);

因此,我应该忽略嵌入在xml中的X509Certificate还是需要对其进行检查... openssl_verify是否足够?我在正确的道路上吗?请任何指导将不胜感激。

最佳答案

使用xmldsig语法签名的XML有3个重要部分:

  • Signature -> KeyInfo包含有关从用于签名数据
  • 的私钥派生的公钥的信息
  • Signature -> SignedInfo包含将要使用上述私钥签名的数据;数据包含有关应如何计算验证的信息,例如:CanonicalizationMethodSignatureMethodReference
  • Signature -> SignatureValue包含通过使用私钥
  • Signature -> SignedInfo签名而生成的签名的值

    从理论上讲,这是代码应如何查找具有以下规范化方法的rsa-sha1算法(由Signature -> SignedInfo -> SignatureMethod指定):专有XML Canonicalization 1.0(省略注释),并提供了x509证书:
    $xmlDoc = new DOMDocument();
    $xmlDoc->loadXML($xmlString);
    
    $xpath = new DOMXPath($xmlDoc);
    $xpath->registerNamespace('secdsig', 'http://www.w3.org/2000/09/xmldsig#');
    
    // fetch Signature node from XML
    $query = ".//secdsig:Signature";
    $nodeset = $xpath->query($query, $xmlDoc);
    $signatureNode = $nodeset->item(0);
    
    // fetch SignedInfo node from XML
    $query = "./secdsig:SignedInfo";
    $nodeset = $xpath->query($query, $signatureNode);
    $signedInfoNode = $nodeset->item(0);
    
    // canonicalize SignedInfo using the method descried in
    // ./secdsig:SignedInfo/secdsig:CanonicalizationMethod/@Algorithm
    $signedInfoNodeCanonicalized = $signedInfoNode->C14N(true, false);
    
    // fetch the x509 certificate from XML
    $query = 'string(./secdsig:KeyInfo/secdsig:X509Data/secdsig:X509Certificate)';
    $x509cert = $xpath->evaluate($query, $signatureNode);
    // we have to re-wrap the certificate from XML to respect the PEM standard
    $x509cert = "-----BEGIN CERTIFICATE-----\n"
        . $x509cert . "\n"
        . "-----END CERTIFICATE-----";
    // fetch public key from x509 certificate
    $publicKey = openssl_get_publickey($x509cert);
    
    // fetch the signature from XML
    $query = 'string(./secdsig:SignatureValue)';
    $signature = base64_decode($xpath->evaluate($query, $signatureNode));
    
    // verify the signature
    $ok = openssl_verify($signedInfoNodeCanonicalized, $signature, $publicKey);
    

    这个lib在php中实现xmldsig方面做得很好。可以在此处找到有关如何验证xmldsig的示例:xmlseclibs。该库还验证了Signature -> SignedInfo -> Reference的摘要值,我在上面省略了这一步骤。

    关于php - 根据PHP中的证书验证SAML响应中的数字签名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19538561/

    10-10 22:14