如何解决在 PHP 中验证 RSA-SHA256 xml在 .NET 中登录并在 PHP 中验证
我收到 XML 请求,包含 MsgBody 标签和签名(在 .net 中完成的签名过程),
我必须验证他们发送的 msg 正文、签名和请求者公钥,但我不能。
我的代码是:
$msg_body = "<MsgBody><Transactions>....</Transactions></MsgBody>";
$signature = "nkI/Z/ySJSxarh..............==";
$verifying_flag = openssl_verify($msg_body,base64_decode($signature),PUBLIC_KEY,OPENSSL_ALGO_SHA256);
我已经试过了:
$rsa = new \Crypt_RSA();
$rsa->loadKey(PUBLIC_KEY);
$verifying_flag = $rsa->verify($msg_body,base64_decode($signature));
$verifying_flag 两种方式都失败,
通过此代码在 .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")));
}
如何验证他们的请求?!
解决方法
首先,您使用SHA-256
对其进行签名,因此您必须在PHP端进行设置:
$rsa->setHash('sha256');
其次,您必须将签名模式设置为默认使用 PKCS#1 方案:
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
最后,由于您在 C# 上使用 Encoding.Unicode.GetBytes
,因此您需要在验证之前将 php 上的消息正文转换为 UTF-16LE
:
$msg_body = mb_convert_encoding($msg_body,'UTF-16LE');
最后的代码应该是这样的:
$rsa = new \Crypt_RSA();
$rsa->loadKey(PUBLIC_KEY);
$rsa->setHash('sha256');
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$msg_body = mb_convert_encoding($msg_body,'UTF-16LE');
$verifying_flag = $rsa->verify($msg_body,base64_decode($signature));
更新
如果你想在 PHP 上生成消息签名,你可以很容易地这样做:
$rsa = new \Crypt_RSA();
$rsa->loadKey(PRIVATE_KEY);
$rsa->setHash('sha256');
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$msg_body = mb_convert_encoding($msg_body,'UTF-16LE');
$signature = base64_encode($rsa->sign($msg_body));
顺便说一句,您可以通过在两种方式(验证和签名)上删除 mb_convert_encoding
行来避免转换消息编码
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。