如何使用sha1ecdsa验证使用公钥的签名数据?

时间:2022-07-28 18:25:02

Knowing little about cryptography I have great problems with what seems to be a simple task.

对密码学知之甚少我对看似简单的任务有很大的问题。

I have .pem certificate, bytes of data, and signature of that data. I want to check if someone changed the data by matching it against signature.

我有.pem证书,数据字节和该数据的签名。我想通过匹配签名来检查是否有人更改了数据。

My try:

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;
  }
}

But it gives me an error

但它给了我一个错误

'Algorithm of certificates key is not supported' (System.NotSupportedException).

'不支持证书密钥算法'(System.NotSupportedException)。

Looking into loaded certificate it says that the signature algorithm is 'sha1ecdsa'.

查看加载的证书,它表示签名算法是'sha1ecdsa'。

I am trying only to verify data against signature. What am I missing here? I would like to do it without any external solutions as it seems to be really trivial task.

我只是想验证数据与签名。我在这里想念的是什么?我想在没有任何外部解决方案的情况下这样做,因为它似乎是非常简单的任务。

Update: I am trying to achieve same functionality as in below Java code:

更新:我正在尝试实现与以下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);
}

2 个解决方案

#1


6  

Although DSA and ECDSA are related, they are not the same. Why not try ECDsaCryptoServiceProvider? Note that the ECDSA support for Elliptic Curves only includes NIST named curves.

尽管DSA和ECDSA是相关的,但它们并不相同。为什么不试试ECDsaCryptoServiceProvider?请注意,ECDSA对椭圆曲线的支持仅包括NIST命名曲线。

#2


0  

.NET 4.6.1 added improved support for ECDSA. While I'm not a fan of your catch-everything-and-return-false, I'll keep it here for comparison:

.NET 4.6.1增加了对ECDSA的改进支持。虽然我不喜欢你的捕获 - 一切都是假的,我会把它留在这里进行比较:

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;
    }
}

Note that in .NET 4.6 the RSA base class has the Sign/Verify methods defined, and in 4.6.1 the ECDsa base class got a similar treatment. New code shouldn't talk about the *CryptoServiceProvider types unless loading pre-existing named keys.

请注意,在.NET 4.6中,RSA基类定义了Sign / Verify方法,而在4.6.1中,ECDsa基类也得到了类似的处理。除非加载预先存在的命名键,否则新代码不应该讨论* CryptoServiceProvider类型。

It's also worth noting that the Get[Algorithm]PublicKey methods return null when the public key isn't of that algorithm type, so a null-check is warranted.

值得注意的是,当公钥不是该算法类型时,Get [Algorithm] PublicKey方法返回null,因此需要进行空检查。

#1


6  

Although DSA and ECDSA are related, they are not the same. Why not try ECDsaCryptoServiceProvider? Note that the ECDSA support for Elliptic Curves only includes NIST named curves.

尽管DSA和ECDSA是相关的,但它们并不相同。为什么不试试ECDsaCryptoServiceProvider?请注意,ECDSA对椭圆曲线的支持仅包括NIST命名曲线。

#2


0  

.NET 4.6.1 added improved support for ECDSA. While I'm not a fan of your catch-everything-and-return-false, I'll keep it here for comparison:

.NET 4.6.1增加了对ECDSA的改进支持。虽然我不喜欢你的捕获 - 一切都是假的,我会把它留在这里进行比较:

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;
    }
}

Note that in .NET 4.6 the RSA base class has the Sign/Verify methods defined, and in 4.6.1 the ECDsa base class got a similar treatment. New code shouldn't talk about the *CryptoServiceProvider types unless loading pre-existing named keys.

请注意,在.NET 4.6中,RSA基类定义了Sign / Verify方法,而在4.6.1中,ECDsa基类也得到了类似的处理。除非加载预先存在的命名键,否则新代码不应该讨论* CryptoServiceProvider类型。

It's also worth noting that the Get[Algorithm]PublicKey methods return null when the public key isn't of that algorithm type, so a null-check is warranted.

值得注意的是,当公钥不是该算法类型时,Get [Algorithm] PublicKey方法返回null,因此需要进行空检查。