如何使用使用 sha1ecdsa 的公钥验证数据是不是符合签名?
Posted
技术标签:
【中文标题】如何使用使用 sha1ecdsa 的公钥验证数据是不是符合签名?【英文标题】:How to verify data against signature with public key that uses sha1ecdsa?如何使用使用 sha1ecdsa 的公钥验证数据是否符合签名? 【发布时间】:2015-05-07 11:08:19 【问题描述】:对密码学知之甚少,我对看似简单的任务有很大的问题。
我有 .pem 证书、数据字节和该数据的签名。 我想通过将数据与签名进行匹配来检查是否有人更改了数据。
我的尝试:
private bool VerifySignature(byte[] data, byte[] signature)
try
X509Certificate certificate = new X509Certificate("cert_filename.pem");
if (certificate == null)
return false;
DSACryptoServiceProvider dsa = (DSACryptoServiceProvider)certificate.PublicKey.Key;
return dsa.VerifyData(data, signatureData);
catch
return false;
但它给了我一个错误
'不支持证书密钥算法' (System.NotSupportedException)。
查看加载的证书,它说签名算法是“sha1ecdsa”。
我只尝试根据签名验证数据。我在这里想念什么? 我想在没有任何外部解决方案的情况下完成它,因为它似乎真的是微不足道的任务。
更新:我正在尝试实现与以下 Java 代码相同的功能:
private boolean verify(byte[] data, byte[] signature)
boolean isLicenseCorrect = false;
Signature sig = Signature.getInstance("SHA1WithECDSA");
sig.initVerify(certificate.getPublicKey());
sig.update(data);
return sig.verify(signature);
【问题讨论】:
根据您的更新,如果您想将 java 代码转换为 C# link 这可能有助于查看 【参考方案1】:虽然 DSA 和 ECDSA 相关,但它们并不相同。为什么不试试ECDsaCryptoServiceProvider
?请注意,ECDSA 对椭圆曲线的支持仅包括 NIST 命名曲线。
【讨论】:
不幸的是,我无法在我的 Windows 窗体代码中访问此类。我只有 ECDsa 和 ECDsaCng,我都无法使用。 好的,那么为什么你不能使用这些类?他们应该提供一个更好的目标,因为DSACryptoServiceProvider
永远不会起作用。请注意,我没有您的设置(我自己没有使用 Windows 窗体,我只知道有关加密的事情以及我在 SO 上看到的内容)。
正如我之前提到的,我对加密技术知之甚少,并且无法自己弄清楚如何解决我的任务。网上有很多使用 RSACryptoServiceProvider 或 DSACryptoServiceProvider 的文章,但我无法使用它们。
我添加了 Java 代码,我想移植到 C# 作为参考。【参考方案2】:
.NET 4.6.1 添加了对 ECDSA 的改进支持。虽然我不喜欢你的 catch-everything-and-return-false,但我将把它放在这里进行比较:
private bool VerifySignature(byte[] data, byte[] signature)
try
// new cannot return null, so no point in a null check. It would have thrown.
using (X509Certificate certificate = new X509Certificate("cert_filename.pem"))
using (ECDsa ecdsa = certificate.GetECDsaPublicKey())
using (RSA rsa = certificate.GetRSAPublicKey())
// Improved DSA is 4.6.2
// You said the cert was ECDSA-SHA1, but that doesn't mean the original data was.
// I assumed it was.
if (ecdsa != null)
return ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA1);
if (rsa != null)
return rsa.VerifyData(data, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
return false;
catch
return false;
请注意,在 .NET 4.6 中,RSA 基类定义了 Sign/Verify 方法,而在 4.6.1 中,ECDsa 基类得到了类似的处理。除非加载预先存在的命名密钥,否则新代码不应谈论 *CryptoServiceProvider 类型。
还值得注意的是,当公钥不是该算法类型时,Get[Algorithm]PublicKey 方法返回 null
,因此需要进行空检查。
【讨论】:
以上是关于如何使用使用 sha1ecdsa 的公钥验证数据是不是符合签名?的主要内容,如果未能解决你的问题,请参考以下文章