使用PHP签名,用C#验证



A有php代码可以签署消息(使用phpseclib 2.0):

function sign($plaintext, $key, $password) {
    $rsa = new RSA();
    $rsa->setPassword($password);
    $rsa->loadKey(file_get_contents($key));
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $signature = $rsa->sign(hash('sha256', $plaintext));
    return base64_encode($signature);
}

公共和私钥格式是PEM。我需要用C#验证此签名。我正在尝试此代码,但它返回false:

public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey)
{
    bool success = false;
    using (var rsa = new RSACryptoServiceProvider())
    {
    var encoder = new UTF8Encoding();
    byte[] bytesToVerify = encoder.GetBytes(originalMessage);
    byte[] signedBytes = Convert.FromBase64String(signedMessage);
    try
    {
        rsa.ImportParameters(publicKey);
        SHA256Managed Hash = new SHA256Managed();
        byte[] hashedData = Hash.ComputeHash(bytesToVerify);
        success = rsa.VerifyData(hashedData, CryptoConfig.MapNameToOID("SHA256"), signedBytes);
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
    }
    finally
    {
        rsa.PersistKeyInCsp = false;
    }
    }
    return success;
}

用法:

RSACryptoServiceProvider rsa = PemKeyUtils.PemKeyUtils.GetRSAProviderFromPemFile("public.key");
MessageBox.Show(VerifyData("my message", @"ZpQMPYlMIgME/H0sRYBnyEf/yJ/eBc5bznYZ2nMFn/I6Ts3u8P3x0QgzbUxPnhUgfKhcrEC2UgffyzWzCfwT3Bs+lm6Q89N5bkWK08WKnWaFxr2GQ6+gNyPyUKUgfy851xIHU7EMR6bZt/IndPC+lAAXSxxddPwLelrI8ktgyMVvMUzfCh3AeNCBuY5sSRwkAKH2myPBThJKNjKSZVEb4tO4oiPPWlBuifqmWvbQeMFuKANY0dZNCUFVjlnkaHnwVNzVs1BhNTEML2MKmWvKofafbtcG8J1F+7PapppZwT7OFqhosCSrrzRX49cR4y/7b0syJozmJSebKDpy6FPefA==", rsa.ExportParameters(false)).ToString());

pemkeyutils类来自此答案。

怎么了?如何使用C#?

验证签名

VerifyData()计算哈希本身,因此您最终在C#代码中两次放哈数据。只需将数据直接提供给VerifyData()而无需自己散步即可。

编辑:好的,现在我看到您也在PHP侧两次放哈希,这是SHA1的第一次,第二次与SHA256一起使用。只需使用SHA256哈希一次,就像示例中的节目一样。

function sign($plaintext, $key, $password) {
    $rsa = new RSA();
    $rsa->setPassword($password);
    $rsa->loadKey(file_get_contents($key));
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $rsa->setHash('sha256')
    $signature = $rsa->sign($plaintext);
    return base64_encode($signature);
}

最新更新