【发布时间】:2018-04-19 21:08:56
【问题描述】:
我无法在 dotnet core v2.0 中重现某些加密功能。这是从 .NET 4.5 项目移植的代码
.NET 4.5 代码
public byte[] SignData(byte[] dataToSign, X509Certificate2 certificate)
{
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
var xml = certificate.PrivateKey.ToXmlString(true);
rsaCryptoServiceProvider.FromXmlString(xml);
var signedBytes = rsaCryptoServiceProvider.SignData(dataToSign, CryptoConfig.MapNameToOID("SHA256"));
return signedBytes;
}
在 dotnet core 中,ToXmlString() 和 FromXmlString() 方法没有实现,所以我使用了辅助类解决方法。除此之外,dotnet 核心实现工作,但是,给定相同的输入数据和证书,它会产生不同的结果。
dotnet core v2.0代码
public byte[] SignData(byte[] dataToSign, X509Certificate2 certificate)
{
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
var rsa = (RSA)certificate.PrivateKey;
var xml = RSAHelper.ToXmlString(rsa);
var parameters = RSAHelper.GetParametersFromXmlString(rsa, xml);
rsaCryptoServiceProvider.ImportParameters(parameters);
SHA256 alg = SHA256.Create();
var signedBytes = rsaCryptoServiceProvider.SignData(dataToSign, alg);
return signedBytes;
}
编辑
dotnet 核心签名数据未通过 .NET 4.5 代码库中的签名验证检查。从理论上讲,签名方法是什么应该没有区别,所以这应该有效,但没有。
public void VerifySignature(byte[] signedData, byte[] unsignedData, X509Certificate2 certificate)
using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PublicKey.Key)
{
if (rsa.VerifyData(unsignedData, CryptoConfig.MapNameToOID("SHA256"), signedData))
{
Console.WriteLine("RSA-SHA256 signature verified");
}
else
{
Console.WriteLine("RSA-SHA256 signature failed to verify");
}
}
}
有谁知道这两种数据签名方法之间是否存在兼容性问题?
编辑 2
为了澄清,这两个代码 sn-ps 都在尝试:
- 获取 X509 证书的私钥,该私钥是 RSA-FULL 并且无法使用 SHA256 编码进行签名
- 创建一个 新的私钥,它是 RSA-AES,可以使用 SHA256 编码进行签名
- 将您的 X509 私钥导入此新私钥中
- 使用此私钥对所需数据进行签名。
在 .NEt4.5 和 dotnet core v2.0 中尝试相同的事情时会出现复杂情况。
似乎框架、库和操作系统之间存在差异。 This answer 声明 RSACryptoServiceProvider 对象依赖于 .NET 4.5 中软件所在机器的 CryptoAPI,this informative post 向您展示了在不同环境中实现方式的差异/框架。
我仍在研究基于此信息的解决方案,但留下了核心问题,即使用上述 dotnet 核心的签名数据无法通过 .NET 4.5 实现进行验证。
【问题讨论】:
-
测试签名的正确方法是验证它们。并非所有签名方案都是确定性的。如果没有代码/测试数据,这个问题就被认为是离题了——好吧,无论如何我都会这样做;给出的代码可能应该运行,但我们无法判断是否有任何其他错误。
-
您的代码,如这里所写,创建一个新密钥,导出它,导入它,并用它签名。所以每次运行你都会有不同的密钥,因此会有不同的签名。另外,不要使用
RSACryptoServiceProvider,使用RSA.Create()。 -
@MaartenBodewes 我添加了失败的验证步骤以进行澄清。
-
如果您的
RSAHelper类中有错误怎么办?我们仍然无法调试它。从我们的角度来看:想象一下 you 需要什么来调试它。请注意,SO 一开始并不是真正的在线调试器;通常很难回答“这段代码在某个地方,不知何故是错误的”。 -
你确定它们没有实现吗?在我看来,他们至少记录在案for .NET core
标签: c# .net cryptography .net-core