如何使用phpseclib在XML签名消息中验证签名? [英] How to validate signature with phpseclib, in a XML signature message?

查看:179
本文介绍了如何使用phpseclib在XML签名消息中验证签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我测试了最终的XML签名文件,并发送无效签名,为什么?
信息:
我准备了这个inf。要使用XML签名签名:

 <?xml version =1.0encoding =UTF-8standalone =否?>< SolicitudRegistro 
xmlns =http://www.cie.mx/SCG/InilidadIdMensaje =f2-8505d81914c>
< FechaEnvio> 2013-02-26T21:08:36< / FechaEnvio>
< Registrante EndPoint =https://200.34.175.46:443/InteropOPE
/ MensajeidadServiceNombre =InstiguaNombreCorto =IMTAURI =op.mx>
< DatosDeContacto AreaOficina =Informatica
CorreoElect =req@tc.ia.mxNombre =RafadinaPuesto =Subdirector nicaciones>
< Telefonos>
< Telefono Extension =NumeroTelefonico =7773293644/>
< / Telefonos>
< / DatosDeContacto>
< CertificadoInstancia> MIIFETCCA / mgAwIBAgIUMDAwMDAwMDAwMDAwMD CERTIFICATE
与SENDER'S PUBLIC KEY =< / CertificadoInstancia>
< / Registrante>
< Reto>
&CadaineCifrada> Ln0BAsnwrNg6IzjW7hk2c / Nxx / x3LZ STRING加密
与私人关键,所以收件人可以使用发件人的证书来确认信息来源=
< / CadenaCifrada>
< / Reto>
< / SolicitudRegistro>

所以我把所有这一切存储在文件result.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'));
/ *加载私钥* /
$ objKey-> loadKey('i.pem',TRUE);
$ objDSig-> sign($ objKey);
/ *添加关联的公钥* /
$ 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){
echoNOT THE SAME;
}
echoDONE;
?>

这将提供一个完整的XML签名(截断一些加密文本):

 <?xml version =1.0encoding =UTF-8standalone =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 =InformaticaCorreoElectronico .....
< Telefonos>
< Telefono Extension =NumeroTelefonico =7773293644/>
< / Telefonos>
< / DatosDeContacto>
< CertificadoInstancia> MIIFETCCA / mgAwIBAgIUMDAwMDY .... =< / CertificadoInstancia>
< / Registrante>
< Reto>
&CadinaCifrada> Ln0BAsnwrNg6IzjW7hk .....< / CadenaCifrada>
< / Reto>
< ds:签名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:参考URI =>< ds:Transforms>< ds:Transform Algorithm = /万维网。
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:转换>< / ds:Transforms>< ds:DigestMethod
Algorithm =http://www.w3.org/2000/09 / xmldsig#sha1
/>< ds: DigestValue> GogFeLcUThvfAeyNrDBroTQaGhA =< / ds:DigestValue>
< / ds:参考>
< / ds:SignedInfo< ds:SignatureValue> N + Btck0X9H81ZUcmrIK3h7LR2CtA86BPaBFE =
< ds:SignatureValue>
< ds:KeyInfo>
< ds:X509Data>
< ds:X509证书> MIIFETCCA / mgAwIB ..... =< / ds:X509证书>
< / ds:X509Data>
< / ds:KeyInfo>




所有这一个问题,
你知道任何示例如何使用PHPSECLIB验证此签名?
或另一个库?
测试页th在展示无效签名是:
https://ope.gob.mx/BrokerInteropQA /Diagnostico/default.aspx



谢谢,
对于这么多信息,我很抱歉,但我试图清楚我的怀疑
mario

解决方案

我会使用 xmlseclibs 作者博客)。现在这可能是使用 openssl _ * 函数它可能会被重写为使用 phpseclib



phpseclib的不足之处在于,对于XML签名,您需要 XML被规范化 将以相同的方式解释,但是 phpseclib 不知道。对于 phpseclib ,它只是一个文本字符串,并被视为文本字符串,它们都不同。但是被视为XML字符串,而不是。


I tested the final XML signature file and it sends, "invalid signatures", why? Information: I have prepared this inf. to be signed with XML signature:

<?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="req@tc.ia.mx" 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>

So I stored all this in file results.xml, then I sign it with phpseclib functions, the code is:

<?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";
?>

This gives a complete XML signature that looks like (truncated some encrypted text):

<?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>

All this for 1 question, do you know any example how to validate this signature using PHPSECLIB? Or another library? the testing page that shows invalid signatures is: https://ope.gob.mx/BrokerInteropQA/Diagnostico/default.aspx

thanks, I apologize for so much information, but I tried to be clear in my doubt mario

解决方案

I'd use xmlseclibs (author-blog). Right now that's probably using the openssl_* functions but it could probably be rewritten to use phpseclib.

The reason phpseclib isn't sufficient is because, for XML Signatures, you need the XML to be canonicalized. and are gonna be interpreted the same way but phpseclib doesn't know that. To phpseclib it's just a text string and treated as text strings they're both different. But treated as XML strings they're not.

这篇关于如何使用phpseclib在XML签名消息中验证签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆