Openssl 在PHP中验证RSA-SHA256 xml(登录.NET并在PHP中验证)
我收到XML请求,包含MsgBody标记和签名(签名过程在.net中完成) 我必须验证他们发送的消息正文、签名和请求者公钥,但我不能 我的代码是:Openssl 在PHP中验证RSA-SHA256 xml(登录.NET并在PHP中验证),openssl,cryptography,rsa,php-openssl,rsa-sha256,Openssl,Cryptography,Rsa,Php Openssl,Rsa Sha256,我收到XML请求,包含MsgBody标记和签名(签名过程在.net中完成) 我必须验证他们发送的消息正文、签名和请求者公钥,但我不能 我的代码是: $msg_body = "<MsgBody><Transactions>....</Transactions></MsgBody>"; $signature = "nkI/Z/ySJSxarh..............=="; $verifying_flag =
$msg_body = "<MsgBody><Transactions>....</Transactions></MsgBody>";
$signature = "nkI/Z/ySJSxarh..............==";
$verifying_flag = openssl_verify($msg_body, base64_decode($signature), PUBLIC_KEY, OPENSSL_ALGO_SHA256);
$Verification_标志在两个方面都失败
此代码在.NET中完成的签名过程:
using System;
public class Program
{
public static string SignMessage(XElement xmlMessage, Collection<string> xPaths, string certificateSerialNumber)
{
string elementsValue = string.Empty;
foreach (vara xPath in xpaths)
{
IEnumerable<XElement> xPathSelectElements = xmlMessage.XPathSelectElements(xPath);
foreach (XElement xPathSelectElements in xPathSelectElements)
{
elementsValue += xPathSelectElements.ToString();
}
}
RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(GetCertificates(certificateSerialNumber).PrivateKey.ToXmlString(true));
RSACryptoServiceProvider.UseMachineKeyStore = true;
rsaCryptoServiceProvider.ExportParameters(false);
rsaCryptoServiceProvider.KeySize = 2048;
return Convert.ToBase64String(rsaCryptoServiceProvider.SignData(Encoding.Unicode.GetBytes(elementsValue), CryptoConfig.MapNameToOID("SHA256")));
}
使用系统;
公共课程
{
公共静态字符串SignMessage(XElement xmlMessage、集合XPath、字符串证书SerialNumber)
{
string elementsValue=string.Empty;
foreach(xpaths中的vara xPath)
{
IEnumerable xPathSelectElements=xmlMessage.xPathSelectElements(xPath);
foreach(xPathSelectElements中的XElement xPathSelectElements)
{
elementsValue+=xPathSelectElements.ToString();
}
}
RSACryptoServiceProvider RSACryptoServiceProvider=新的RSACryptoServiceProvider();
rsacyptoServiceProvider.FromXmlString(GetCertificates(certificateSerialNumber).PrivateKey.ToXmlString(true));
rsacryptServiceProvider.UseMachineKeyStore=true;
rsacryptserviceprovider.ExportParameters(false);
rsacryptserviceprovider.KeySize=2048;
返回Convert.ToBase64String(rsaCryptoServiceProvider.SignData(Encoding.Unicode.GetBytes(elementsValue)、CryptoConfig.MapNameToOID(“SHA256”);
}
如何验证他们的请求?!首先,您使用的是
SHA-256
,因此您必须在PHP端设置它:
$rsa->setHash('sha256');
其次,您必须设置签名模式以默认使用PKCS#1方案:
$rsa->setSignatureMode(CRYPT\u rsa\u SIGNATURE\u PKCS1);
最后,由于在C#上使用的是Encoding.Unicode.GetBytes
,因此在验证之前,需要将php上的消息体转换为UTF-16LE
:
$msg_body=mb_convert_编码($msg_body,'UTF-16LE');
最后,代码应该是这样的:
$rsa=new\Crypt_rsa();
$rsa->loadKey(公钥);
$rsa->setHash('sha256');
$rsa->setSignatureMode(密码\u rsa\u签名\u PKCS1);
$msg_body=mb_convert_编码($msg_body,'UTF-16LE');
$verifying_flag=$rsa->verify($msg_body,base64_decode($signature));
更新
如果要在PHP上生成消息签名,可以轻松执行以下操作:
$rsa=new\Crypt_rsa();
$rsa->loadKey(私钥);
$rsa->setHash('sha256');
$rsa->setSignatureMode(密码\u rsa\u签名\u PKCS1);
$msg_body=mb_convert_编码($msg_body,'UTF-16LE');
$signature=base64_encode($rsa->sign($msg_body));
顺便说一句,您可以通过在两种方式上删除mb\u convert\u encoding
行来避免转换消息编码(验证和签名)
using System;
public class Program
{
public static string SignMessage(XElement xmlMessage, Collection<string> xPaths, string certificateSerialNumber)
{
string elementsValue = string.Empty;
foreach (vara xPath in xpaths)
{
IEnumerable<XElement> xPathSelectElements = xmlMessage.XPathSelectElements(xPath);
foreach (XElement xPathSelectElements in xPathSelectElements)
{
elementsValue += xPathSelectElements.ToString();
}
}
RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(GetCertificates(certificateSerialNumber).PrivateKey.ToXmlString(true));
RSACryptoServiceProvider.UseMachineKeyStore = true;
rsaCryptoServiceProvider.ExportParameters(false);
rsaCryptoServiceProvider.KeySize = 2048;
return Convert.ToBase64String(rsaCryptoServiceProvider.SignData(Encoding.Unicode.GetBytes(elementsValue), CryptoConfig.MapNameToOID("SHA256")));
}