C# VerifyHash似乎在Windows上工作,但在Linux上失败

C# VerifyHash似乎在Windows上工作,但在Linux上失败,c#,.net-core,rsa,C#,.net Core,Rsa,我正在创建一个.net核心应用程序,我希望它能在Windows和Linux上运行。 在我的应用程序中,我使用VerifyHash验证文件哈希,在Windows上一切都很好,但在linux上却失败了 public static bool ValidateSignature(byte[] sha256, string signature) { if (_rsaCryptoServiceProvider == null || string.IsNullOrEmpty(signature))

我正在创建一个.net核心应用程序,我希望它能在Windows和Linux上运行。 在我的应用程序中,我使用VerifyHash验证文件哈希,在Windows上一切都很好,但在linux上却失败了

public static bool ValidateSignature(byte[] sha256, string signature)
{
    if (_rsaCryptoServiceProvider == null || string.IsNullOrEmpty(signature))
    {
        return false;
    }

    var test = _rsaCryptoServiceProvider.VerifyHash(sha256, CryptoConfig.MapNameToOID("SHA256"), Base64.Decode(signature));
    Console.WriteLine("SHA256: " + Sha256ToString(sha256));
    Console.WriteLine("SIGNATURE: " + signature);
    Console.WriteLine("Match: " + test);

    return test;
}
我添加了这些调试写线来检查函数是否获得相同的数据,它确实如此

这是我从Windows的输出:

SHA256: 4146024cf95ed34573d2dabde7569f1ca3611091760060c9fee718522890519e
SIGNATURE: H+FOxGDT3vE8fA6oyKIH56fVCipRkf6oidxU0KnvCvADGu083h196dPv4lWwi5i0XATygABqEbS0iwLBXFtrhoX5wxLRkpnpnZjTEgcONWrKe78wYKKwAqUfVWyT6VuQGX3bpcSHlvTUsbtZAins2BBp7kS2CtivVwU1G87+cNs=
Match: True
这是Linux的输出:

SHA256: 4146024cf95ed34573d2dabde7569f1ca3611091760060c9fee718522890519e
SIGNATURE: H+FOxGDT3vE8fA6oyKIH56fVCipRkf6oidxU0KnvCvADGu083h196dPv4lWwi5i0XATygABqEbS0iwLBXFtrhoX5wxLRkpnpnZjTEgcONWrKe78wYKKwAqUfVWyT6VuQGX3bpcSHlvTUsbtZAins2BBp7kS2CtivVwU1G87+cNs=
Match: False
哈希和签名完全相同,但linux无法验证它

我使用openssl检查了linux机器上的签名是否匹配,以下是我的输出:

$ cat mod.dll | openssl dgst -sha256
(stdin)= 4146024cf95ed34573d2dabde7569f1ca3611091760060c9fee718522890519e

$ cat mod.dll | openssl dgst -sha256 -binary | openssl rsautl -inkey key -sign | base64
H+FOxGDT3vE8fA6oyKIH56fVCipRkf6oidxU0KnvCvADGu083h196dPv4lWwi5i0XATygABqEbS0
iwLBXFtrhoX5wxLRkpnpnZjTEgcONWrKe78wYKKwAqUfVWyT6VuQGX3bpcSHlvTUsbtZAins2BBp
7kS2CtivVwU1G87+cNs=
正如您可以从openssl匹配中看到的签名和哈希一样,签名是100%正确的,VerifyHash函数中有一些错误

下面是我创建和处置服务提供商的代码:

private static void _UpdateCrypto()
{
    var key = PublicKeyFactory.CreateKey(_key);
    var rsaKey = (RsaKeyParameters) key;

    var parameters = new RSAParameters
    {
        Modulus = rsaKey.Modulus.ToByteArrayUnsigned(),
        Exponent = rsaKey.Exponent.ToByteArrayUnsigned()
    };

    _rsaCryptoServiceProvider = new RSACryptoServiceProvider();
    _rsaCryptoServiceProvider.ImportParameters(parameters);
}

public static void Dispose()
{
    _rsaCryptoServiceProvider?.Dispose();
}

_键是byte[]字段,它是加载到字节数组中的.der文件,在程序开始时调用_UpdateCrypto()。

好的,我只是使用了BouncyCastle库,效果很好

这是我的代码,用于在有人需要时验证签名:

public static bool ValidateSignature(byte[] sha256, string signature)
{
    if (_asymmetricBlockCipher == null || string.IsNullOrEmpty(signature))
    {
        return false;
    }

    var decoded = Base64.Decode(signature);
    return _asymmetricBlockCipher.ProcessBlock(decoded, 0, decoded.Length).SequenceEqual(sha256);
}

检查在Linux中还原已解码的Base64字符串是否可以做到这一点。我认为这个问题与不同机器上的字节顺序有关。这似乎不是一个字节顺序问题,还原解码的base64没有帮助。你能提供负责实例化和处理提供程序类的代码吗?我将它添加到问题中。
VerifyHash(哈希,签名,HashAlgorithmName.SHA256,rsasignatureAdding.Pkcs1)
work?感谢您的回复。我想您在Linux上使用的是Mono,您可能需要提交一份错误报告。Mono似乎是.NET类的一个洁净室实现,因此这可能表明存在错误。您可能需要在您的计算机上包含Mono的版本,以防万一。我没有使用Mono,我使用的是.NET C矿石2.1.4