简体   繁体   English

登录 phpseclib 并在 C# 中验证

[英]Sign in phpseclib and Verify in C#

I am trying to verify the authenticity of a message across PHP (phplibsec) and C#.我正在尝试通过 PHP (phplibsec) 和 C# 验证消息的真实性。

However, there seem to be some issues with the verification on the C# side.但是,C# 端的验证似乎存在一些问题。

What I have tried:我试过的:

  1. Provide the public key to C# but make C# compute the hash and the signature then verify (Output: True)将公钥提供给 C# 但让 C# 计算 hash 和签名然后验证(输出:真)
  2. Change the hash to the one computed in PHP but make C# compute the signature then verify (Output: True)将 hash 更改为 PHP 中计算的值,但让 C# 计算签名然后验证(输出:真)
  3. Make C# use PHP's computed hash and signature then verify (Output: False)使 C# 使用 PHP 计算的 hash 和签名然后验证(输出:假)

PHP Code: PHP 代码:

//Load private key
$rsa = PublicKeyLoader::load("... private key ...", false);

//Set PKCS1 mode
$rsa->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1)->withHash("sha256");

//Generate and Convert the hash from 64 byte hex to 32 byte
$hash = pack("H*", hash("sha256", "test"));

//Sign the hash and encode it
$signed_hash = base64_encode($rsa->sign($hash));

//Encode the hash
$hash = base64_encode($hash);

C# Code: C# 代码:

static void Main()
{
    //Create a new instance of RSA.
    using (RSA rsa = RSA.Create())
    {
        //Load public key from XML string
        rsa.FromXmlString("... public key ...");

        //Create an RSAPKCS1SignatureDeformatter object and pass it the RSA instance
        //to transfer the key information.
        RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(rsa);
        RSADeformatter.SetHashAlgorithm("SHA256");

        //decode the hash
        var hash = Convert.FromBase64String("SHA256 Hash As Base64");
        var signedHash = Convert.FromBase64String("SHA256 Hash Signature As Base64");

        //Verify the hash and display the results to the console.
        if (RSADeformatter.VerifySignature(hash, signedHash))
        {
            Console.WriteLine("True");
        }
        else
        {
            Console.WriteLine("False");
        }
    }
}

There are issues in both codes:两个代码都存在问题:

  • By default phpseclib uses PSS as default (here and in the following v3 assumed).默认情况下,phpseclib 使用 PSS 作为默认值(此处和以下 v3 假定)。 Padding is explicitly set to PKCS#1 v1.5 though, but it is not used because the return value is not applied.填充虽然显式设置为 PKCS#1 v1.5,但由于未应用返回值,因此未使用它。 For the padding change to take effect, the return value must be considered.要使填充更改生效,必须考虑返回值。
    By the way, SHA256 is the default here.顺便说一句,这里默认使用 SHA256。 And RSA::ENCRYPTION_PKCS1 is ignored in the context of signing/verifying and can be removed as well.并且RSA::ENCRYPTION_PKCS1在签名/验证的上下文中被忽略,也可以被删除。

  • phpseclib hashes the data implicitly when signing. phpseclib 在签名时隐式散列数据。 Since in the current phpseclib code the hash is additionally generated explicitly, double hashing is done.由于在当前的 phpseclib 代码中还显式生成了 hash,因此完成了双重哈希。 This double hashing is not necessary and can be removed.这种双重哈希不是必需的,可以删除。

  • The double Base64 encoding at the end is also unnecessary and can be removed as well.最后的双 Base64 编码也是不必要的,也可以删除。

    Overall:全面的:

     ... //Set PKCS1 mode $rsa = $rsa->withPadding(RSA::SIGNATURE_PKCS1)->withHash("sha256"); //Sign the hash and encode it $signature = base64_encode($rsa->sign("test")); print($signature. PHP_EOL);

    PKCS#1v1.5 is deterministic, ie for the same input data, repeated signing results in the same signature. PKCS#1v1.5 是确定性的,即对于相同的输入数据,重复签名会产生相同的签名。


  • Unlike the PHP code, no implicit hashing is done in the C# code, so that must happen explicitly.与 PHP 代码不同,C# 代码中没有进行隐式散列,因此必须显式进行。

    The verification with the C# code is then possible with:然后可以使用 C# 代码进行验证:

     ... var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes("test")); var signature = Convert.FromBase64String("<Base64 encoded signature from PHP code>"); Console.WriteLine(RSADeformatter.VerifySignature(hash, signature)); // True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM