C# RSACryptServiceProvider.VerifyData始终返回false
下面是我的C#程序,它验证使用phpseclib的php脚本的响应C# RSACryptServiceProvider.VerifyData始终返回false,c#,php,rsa,public-key-encryption,phpseclib,C#,Php,Rsa,Public Key Encryption,Phpseclib,下面是我的C#程序,它验证使用phpseclib的php脚本的响应 static void Main(string[] args) { var payment = "VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ=";
static void Main(string[] args)
{
var payment =
"VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ=";
var signature =
"V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk=";
var sigByte = Convert.FromBase64String(signature);
var payBite = Convert.FromBase64String(payment);
Verify(payBite, sigByte);
}
public static bool Verify(byte[] payment, byte[] signature)
{
var key = Resources.PublicKey;
var cipher = Crypto.DecodeX509PublicKey(key);
var res = cipher.VerifyData(payment, "SHA256", signature);
return res;
}
使用的公钥如下所示:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ
/GQFct8GoUevNELG7wIDAQAB
-----END PUBLIC KEY-----
但是验证方法似乎总是返回false。你知道为什么会这样吗
供应商给我的php代码中也有相同的内容
<?php
//load RSA library
include 'Crypt/RSA.php';
//initialize RSA
$rsa = new Crypt_RSA();
//decode & get POST parameters
$payment = base64_decode("VUQxMzE1MTg0OTk0MDM2MzIyMDJ8VDAwMDAxN0kxMFVEMTMxNTE4NDk5NDAzNjMyMjAyfDIwMTctMTAtMDd8MHxwYXltZW50IHN1Y2Nlc3NmdWx8MjAyNTQ=");
$signature = base64_decode("V0T9ZedZW8oB9uy4PazRIxWHvJ7rR+FVtnGjUy30mSKqgmEceZWE1aBvkQWeG4ERjAXHjsRge0D0MlHd9zvXjrLog+G5nWBHIu52O0srCd9d71JVztMQy8fV5oSnRPtlUpgdmn8QDnJ27XrbaHzNxnFyybTQhmbfxkT0oJ0MEOk=");
//load public key for signature matching
$publickey = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25
HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYY
f/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ
/GQFct8GoUevNELG7wIDAQAB
-----END PUBLIC KEY-----";
$rsa->loadKey($publickey);
//verify signature
$signature_status = $rsa->verify($payment, $signature);
//get payment response in segments
//payment format: order_id|order_refference_number|date_time_transaction|payment_gateway_used|status_code|comment;
$responseVariables = explode('|', $payment);
//display values
echo $signature_status;
echo '<br/>';
var_dump($responseVariables);
?>
知道我做错了什么吗。我尝试在C代码中传递“SHA512”、“MD5”,但仍然返回false 看来供应商没有使用PKCS1,他使用的是PSS。通过这种方式进行验证(需要弹性城堡!):
看起来供应商没有使用PKCS1,他使用的是PSS。通过这种方式进行验证(需要弹性城堡!):
PSS在.NET 4.6+的框架中受支持,但需要使用RSACng类(RSACyptoServiceProvider所基于的CAPI不提供该类)
PSS在.NET 4.6+的框架中受支持,但需要使用RSACng类(RSACyptoServiceProvider所基于的CAPI不提供该类)
根据phpseclib文档,默认哈希算法是sha1。“你试过C#中的那个吗?”迈克尔·耶普。这也产生了同样的结果,我想知道您是否也需要(在PHP中)
$rsa->setEncryptionMode(CRYPT\u rsa\u ENCRYPTION\u PKCS1)代码>。默认情况下,phpseclib使用OAEP加密。它比PKCS1更安全,但不太常用。@neubert php实际上来自一家供应商。我对它没有太多控制权。您是否确定供应商使用CRYPT\u RSA\u SIGNATURE\u PKCS1
而不是CRYPT\u RSA\u SIGNATURE\u PSS
?根据phpseclib文档,默认哈希算法是sha1。“你试过C#中的那个吗?”迈克尔·耶普。这也产生了同样的结果,我想知道您是否也需要(在PHP中)$rsa->setEncryptionMode(CRYPT\u rsa\u ENCRYPTION\u PKCS1)代码>。默认情况下,phpseclib使用OAEP加密。它比PKCS1更安全,但不太常用。@neubert php实际上来自一家供应商。我对它没有太多控制权。您确定供应商使用的是CRYPT\u RSA\u签名\u PKCS1
而不是CRYPT\u RSA\u签名\u PSS
?是的。。我想他们的文档和实现似乎有所不同。非常感谢你的想法。是的。。我猜他们的文档和实现似乎有所不同。非常感谢你的想法。什么是Crypto.DecodeX509PublicKey?那是从哪里来的?我似乎无法在我的代码中正确引用它。@Ristogod它是在问题的原始代码中调用的函数。从这个答案的角度来看,这是一个黑匣子。什么是Crypto.DecodeX509PublicKey?那是从哪里来的?我似乎无法在我的代码中正确引用它。@Ristogod它是在问题的原始代码中调用的函数。从这个答案的角度来看,这是一个黑匣子。
public static bool Verify(byte[] payment, byte[] signature)
{
var pub = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSiXzUuH9ePZgSLYrzZ0qhta25HCb+WG48wIKUl+cQNC/Fl/KZG2cSwRXdo8KZLVWWO5qwzplfTWEylg4IqRA48rYYf/b+Y7QhORKeAws4pttLZJBbh1mIbZ9HXfQ+zBjP+zfJZ1YjSFs2uZdwSt1itUcJ/GQFct8GoUevNELG7wIDAQAB";
byte[] raw = Convert.FromBase64String(pub);
AsymmetricKeyParameter aKey = PublicKeyFactory.CreateKey(raw);
RsaKeyParameters rKey = (RsaKeyParameters)aKey;
PssSigner pss = new PssSigner(new RsaEngine(), new Sha1Digest(), 20);
pss.Init(false, rKey);
pss.BlockUpdate(payment, 0, payment.Length);
var res = pss.VerifySignature(signature);
return res;
}
public static bool Verify(byte[] payment, byte[] signature)
{
var key = Resources.PublicKey;
// Change the function this calls to return RSACng instead of RSACryptoServiceProvider.
RSA cipher = Crypto.DecodeX509PublicKey(key);
// or, failing being able to change it:
RSA tmp = new RSACng();
tmp.ImportParameters(cipher.ExportParameters(false));
cipher = tmp;
return cipher.VerifyData(
payment,
signature,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pss);
}