我正在创建一个.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;
}
我添加了这些调试WriteLines以检查函数是否获得相同的数据,并且确实如此。
这是我在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();
}
_key是byte []字段,它是一个加载到字节数组中的.der文件,在程序开始时调用_UpdateCrypto()。
答案 0 :(得分:1)
好的,我只使用了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);
}