2013-02-28 97 views
0

我測試了最終的XML簽名文件,它發送「無效簽名」,爲什麼? 信息: 我已經準備好了這個inf。與XML簽名進行簽名:如何用XML簽名消息中的phpseclib驗證簽名?

<?xml version="1.0" encoding="UTF-8" standalone="no"?><SolicitudRegistro 
    xmlns="http://www.cie.mx/SCG/Inilidad" IdMensaje="f2-8505d81914c"> 
<FechaEnvio>2013-02-26T21:08:36</FechaEnvio> 
<Registrante EndPoint="https://200.34.175.46:443/InteropOPE 
    /MensajeidadService" Nombre="Instigua" NombreCorto="IMTA" URI="op.mx"> 
<DatosDeContacto AreaOficina="Informatica" 
    CorreoElect="[email protected]" Nombre="Rafadina" Puesto="Subdirector nicaciones" > 
<Telefonos> 
<Telefono Extension=" " NumeroTelefonico="7773293644" /> 
</Telefonos> 
</DatosDeContacto> 
<CertificadoInstancia>MIIFETCCA/mgAwIBAgIUMDAwMDAwMDAwMDAwMD CERTIFICATE 
    WITH SENDER'S PUBLIC KEY=</CertificadoInstancia> 
</Registrante> 
<Reto> 
<CadenaCifrada>Ln0BAsnwrNg6IzjW7hk2c/Nxx/x3LZ STRING ENCRYPTED 
    WITH PRIVATE KEY SO RECEIVER CAN AUTHENTICATE SOURCE WITH SENDER'S CERTIFICATE= 
</CadenaCifrada> 
</Reto> 
</SolicitudRegistro> 

所以我存儲所有這些文件results.xml,然後我跟phpseclib功能簽名,代碼:

<?php 
require('xmlseclibs.php'); 
if (file_exists('./firmas/sign-basic-test_mio.xml')) { 
    unlink('./firmas/sign-basic-test_mio.xml'); 
} 
$doc = new DOMDocument(); 
$doc->load('./firmas/results.xml'); 
$objDSig = new XMLSecurityDSig(); 
$objDSig->setCanonicalMethod(XMLSecurityDSig::C14N); 
$objDSig->addReference($doc, XMLSecurityDSig::SHA1, 
    array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', 
    array('http://www.w3.org/TR/1999/REC-xpath-19991116' => 
    array("query" => "ancestor-or-self::*[local- 
    name()='SolicitudRegistro']"))),array("force_uri"=>true)); 
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private')); 
/* load private key */ 
$objKey->loadKey('i.pem', TRUE); 
$objDSig->sign($objKey); 
/* Add associated public key */ 
$objDSig->add509Cert(file_get_contents('instancia_imta_ope.crt')); 
$objDSig->appendSignature($doc->documentElement); 
$doc->save('./firmas/sign-basic-test_mio.xml'); 
$sign_output = file_get_contents('./firmas/sign-basic-test_mio.xml'); 
$sign_output_def = file_get_contents('./firmas/sign-basic-test_mio.res'); 
if ($sign_output != $sign_output_def) { 
    echo "NOT THE SAME"; 
} 
echo "DONE"; 
?> 

這給出了一個完整的XML簽名看起來像(截斷一些加密的文本):

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<SolicitudRegistro xmlns="http://www.cb.mx/SCG/Interlidad" 
    IdMensaje="f2e140eb-2b09-44ab-8504-87b25d81914c"> 
<FechaEnvio>2013-02-26T21:08:36</FechaEnvio> 
<Registrante EndPoint="https://200.34.175.46:443/InteropOPE..... 
<DatosDeContacto AreaOficina="Informatica" CorreoElectronico..... 
<Telefonos> 
<Telefono Extension=" " NumeroTelefonico="7773293644"/> 
</Telefonos> 
</DatosDeContacto> 
<CertificadoInstancia>MIIFETCCA/mgAwIBAgIUMDAwMDY....=</CertificadoInstancia> 
</Registrante> 
<Reto> 
<CadenaCifrada>Ln0BAsnwrNg6IzjW7hk.....</CadenaCifrada> 
</Reto> 
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:SignedInfo><ds:CanonicalizationMethod 
    Algorithm="http://ww.org/TR/2001 /REC-xml-c14n-20010315"/> 
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 
    <ds:Reference URI=""><ds:Transforms><ds:Transform Algorithm="http://www. 
    w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform 
    Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> 
    <ds:XPath>ancestor-or-self::*[local-name()='SolicitudRegistro']</ds:XPath> 
    </ds:Transform></ds:Transforms><ds:DigestMethod 
    Algorithm="http://www.w3.org/2000/09 /xmldsig#sha1" 
    /><ds:DigestValue>GogFeLcUThvfAeyNrDBroTQaGhA=</ds:DigestValue> 
</ds:Reference> 
</ds:SignedInfo><ds:SignatureValue>N+Btck0X9H81ZUcmrIK3h7LR2CtA86BPaBFE= 
</ds:SignatureValue> 
<ds:KeyInfo> 
<ds:X509Data> 
<ds:X509Certificate>MIIFETCCA/mgAwIB.....=</ds:X509Certificate> 
</ds:X509Data> 
</ds:KeyInfo> 

所有這1個問題, 你知道任何示例如何使用PHPSECLIB驗證此簽名? 或其他圖書館? 測試頁面,顯示無效簽名是: https://ope.gob.mx/BrokerInteropQA/Diagnostico/default.aspx

感謝, 我這麼多信息道歉,但我想清楚,我懷疑 馬里奧

+0

可否請你看一看的常見問題解答,迴應評論,接受答案\ – 2013-03-02 23:05:39

回答

3

我會用xmlseclibsauthor-blog)。現在可能使用openssl_* functions,但它可能會被重寫爲使用phpseclib

phpseclib不足的原因是因爲對於XML簽名,您需要XML to be canonicalized會被解釋爲相同的方式,但phpseclib不知道。到phpseclib它只是一個文本字符串,並被視爲文本字符串,他們都是不同的。但是被視爲不是的XML字符串。

+0

注:我對你的答案註釋高於您的顯示 – user1873420 2013-02-28 22:15:04

0

我使用以下與xmlseclibs,但它發送給我失敗!!!!,有什麼可能是錯的?

<?php 
require('xmlseclibs.php'); 
$doc = new DOMDocument(); 
$arTests = array('SIGN_TEST'=>'./firmas/sign-basic-test_mio.xml'); 
foreach ($arTests AS $testName=>$testFile) { 
    $doc->load($testFile); 
    $objXMLSecDSig = new XMLSecurityDSig(); 
    $objDSig = $objXMLSecDSig->locateSignature($doc); 
    if (! $objDSig) { 
    throw new Exception("Cannot locate Signature Node"); 
    } 
$objXMLSecDSig->canonicalizeSignedInfo(); 
$objXMLSecDSig->idKeys = array('wsu:Id'); 
$objXMLSecDSig->idNS = array('wsu'=>'http://docs.oasis-open.org/wss/2004/01/oasis- 
    200401-wss-wssecurity-utility-1.0.xsd'); 
$retVal = $objXMLSecDSig->validateReference(); 
if (! $retVal) { 
    throw new Exception("Reference Validation Failed"); 
} 
$objKey = $objXMLSecDSig->locateKey(); 
if (! $objKey) { 
    throw new Exception("We have no idea about the key"); 
} 
$key = NULL; 
$objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); 
if (! $objKeyInfo->key && empty($key)) { 
    $objKey->loadKey('i.pem', TRUE); 
} 
if ($objXMLSecDSig->verify($objKey)) { 
    print "Signature validateddd!"; 
} else { 
    print "Failure!!!!!!!!"; 
} 
print "\n"; 
} 
?> 
+0

以前的結果後,我會嘗試phpseclib,但你說是不夠的,所以也許你會看到這個驗證代碼中缺少什麼或者錯誤,謝謝neubert – user1873420 2013-02-28 22:03:03

+0

注意:sign-basic-test_mio.xml具有完整的XML簽名,而i.pem是私鑰 – user1873420 2013-02-28 22:12:05