Php 加密vs签名,使用Crypt_RSA的罕见输出

Php 加密vs签名,使用Crypt_RSA的罕见输出,php,xml,encryption,sign,phpseclib,Php,Xml,Encryption,Sign,Phpseclib,我正在尝试用以下符号为字符串签名: $rsa = new Crypt_RSA(); //$rsa->setPassword('*****'); $rsa->loadKey(file_get_contents('i.pem')); // private key $plaintext = 'f2e140eb-2b09-44ab-8504-87b25d81914c'; $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); $cipher

我正在尝试用以下符号为字符串签名:

$rsa = new Crypt_RSA();
//$rsa->setPassword('*****');
$rsa->loadKey(file_get_contents('i.pem')); // private key
$plaintext = 'f2e140eb-2b09-44ab-8504-87b25d81914c';
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$ciphertext = $rsa->sign($plaintext);
$reto = base64_encode($ciphertext);
当我在本地验证时,使用:

$pubb_key = openssl_pkey_get_public(file_get_contents('instancia_imta_ope.crt'));      
$keyData = openssl_pkey_get_details($pubb_key);
$pkeyy = $keyData['key'];
$rsa->loadKey($pkeyy); // PUBLIC key
echo $rsa->verify($plaintext, $ciphertext) ? 'verified' : 'unverified';
它表明,, 当我对我的代理使用测试页面时,同样的代码不起作用。它无法恢复原始字符串。 为了使用不同的东西,我尝试了以下奇怪的代码:

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('i.pem')); // PRIVATE key, IT SHOULD BE PUBLIC
$plaintext = 'f2e140eb-2b09-44ab-8504-87b25d81914c';
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$ciphertext = $rsa->encrypt($plaintext);
$reto = base64_encode($ciphertext);
这很奇怪或者不合逻辑,因为我使用私钥加密,它被认为是公钥,而目标使用私钥来解密消息。奇怪的是,这个weid代码使tester页面发送OK,它恢复字符串。我不知道为什么。 所有这些都是一个更大消息的一部分,最终用xml签名处理,当我处理所有消息(添加xml签名)时,代理的另一个测试页面发送无效签名,我敢打赌这是因为奇怪的代码。没关系,问题是: 为什么正确的代码(rsa->sign…)不起作用?你对这一切有什么看法? 谢谢
mario在处理加密和认证时。您使用一个私钥进行签名,该私钥保证它来自您(或该密钥的其他持有者,该密钥应安全地保存在一个安全的密钥库中)

您可以使用公钥进行加密,以便只有预期的接收者可以解密(或者非对称对的私钥的其他持有者)


这就是SSL在后台的大致工作方式(跳过加密的AES对称密钥部分)。

那么代码在一台机器上工作,而不是在另一台机器上工作?在这种情况下,您的.crt文件可能会有所不同。这就是说,您不需要使用
openssl.*
来提取公钥——您可以使用phpseclib来提取公钥。例如

<?php
include('File/X509.php');

$x509 = new File_X509();
$cert = $x509->loadX509('...'); // see google.crt

echo $x509->getPublicKey()->getPublicKey();
?>

我不太确定你问的加密问题是什么。。虽然通常使用公钥加密,但也可以使用私钥加密。它们都做相同的运算——模幂运算。我无法在测试仪页面上发表评论,因为它的来源尚未发布。

整个文档的示例(为安全起见,字段被截断),请参见UPPERSOCRE评论:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SolicitudRegistro xmlns="http://www.cidge.gob.mx/SCG/Interoperabilidad"     
IdMensaje="f2e140eb-2b09-44ab-8504-87b25d81914c">
<FechaEnvio>2013-04-19T02:09:08</FechaEnvio>
<Registrante EndPoint="https://200.34.175.46:443/InteropOPE    
/MensajeInteroperabilidadService" Nombre="Institnologia del Agua"  
NombreCorto="IMTA" URI="op.mx">
<DatosDeContacto AreaOficina="Inmatica" 
CorreoElectronico="jbloc.imta.mx"     
Nombre="JoChacon" Puesto="Subdireclecomunicaciones">
<Telefonos>
<Telefono Extension=" " NumeroTelefonico="7773293644"/>
</Telefonos>
</DatosDeContacto>
<CertificadoInstancia>MIIFETCCA/mgAwIBAgIUMDAwMDAwM
</Registrante>
<Reto>         //THIS IS THE STRING SIGNED WITH PRIVATE KEY, is part of info
<CadenaCifrada>Ln0BAsnwrNg6IzjW7hk2c/Nxx/x  //I COPY THIS IN FIRST TESTER AND FAILS
</Reto>                              //UNLESS I USE ENCRYPT CODE WITH PRIV KEY (RARE)
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.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-signatu
<ds:KeyInfo><ds:X509Data>   
<ds:X509Certificate>MIIFETCCA/mgAwIBAgIUMDAwMDAwMDAwMDAwMDAwMDI1MzMwDQY

2013-04-19T02:09:08
MIIFETCCA/MGAWIBAGIUMDAWM
//这是用私钥签名的字符串,是信息的一部分
Ln0BAsnwrNg6IzjW7hk2c/Nxx/x//我在第一个测试仪中复制了此项,但失败
//除非我使用私钥加密代码(罕见)

谢谢Jeff,这就是为什么我把奇怪的,你知道为什么符号代码(代码的第一个parragraph)不起作用吗?”,当我和我的经纪人一起使用测试页面时,同样的代码,不起作用”-我必须真正看到测试页面。你会错过一个不同点,可能你忘记了Base64解码?杰夫,你是说测试仪页面中的代码?同意,我将向代理请求它,以查看如何进行验证…但首先,我必须修复第一部分,正确签名消息的该部分(字符串f2e140eb-…)。可能解决了这个问题后,测试人员运行OkClarify,第一个测试页面,验证字符串的符号,第二个测试页面,验证整个消息,其中已经包含xml签名。第一个页面是我试图解决的问题,但不是使用iLogic代码,而是使用符号codeHi neubert,不完全是,代码在f中工作第一个测试仪,第一个测试仪只测试字符串f2e的符号,这个符号是文档的一部分,然后我对整个文档进行xml签名,然后在第二个测试仪中测试生成的签名文档,在那里它发送“无效签名”“。我喜欢的是应用代码对字符串进行签名,然后将xml签名应用于整个文档,并将生成的已签名文档放入测试仪。我无法达到这一点,因为当我使用私钥对字符串进行签名时,第一个测试仪发送了一个错误,没有恢复原始字符串,垃圾你能发布非工作代码吗?听起来您发布了工作代码,然后发布了一些与加密相关的无关代码,但我在OP中没有看到任何与XML签名相关的内容。您是如何使用Crypt_RSA生成它们的,以及如何验证它们的?idk关于XML签名的内容太多了,但我知道在生成sig之前必须对XML进行规范化,这样您将始终获得相同的sig。例如,如果没有canoicalization,
val
val
很可能被视为同一件事。$rsa=new Crypt_rsa()//$rsa->setPassword('*****')$rsa->loadKey(文件获取内容('i.pem');//私钥$plaintext='f2e140eb-2b09-44ab-8504-87b25d81914c'$rsa->setSignatureMode(加密rsa签名PKCS1)$密文=$rsa->符号($明文)$reto=base64_编码($ciphertext);上述代码在检测仪中不起作用。我不知道为什么,它使用的是私钥和私有函数,它应该可以工作,有什么问题吗?第一个测试人员的链接:这是现在的解决方案,还是只是一个附加注释,或者只是其他什么?这与你的问题有什么关系?您能更清楚地说明这些注释是关于什么的吗?当然,hakre,这段代码代表最终的文档,带有xml签名。有一个用Crypt_RSA函数签名的字段(reto)。代理有一个页面来测试这个第一个签名,但它不起作用(所以我无法到达第二个页面)。如果我使用加密功能来签名,第一页发送ok,但是整个文档的第二个测试页失败,这表明签名无效,这就是为什么我问第一个代码有什么问题,希望有人看到问题。帖子的代码,是reto字段的符号,生成整个文档的代码,可能是奇怪的代码它是正确的,使用私钥加密,所有人都使用解密,但只使用我的公钥,也许这就是为什么第一页发送OK的原因。也许我的疑问是,为什么这两个代码,一个使用rsa->sign,另一个使用rsa->encrypt,不会给出相同的结果,谢谢澄清