gpt4 book ai didi

c# - DSA 使用相同的数据生成不同的签名

转载 作者:太空宇宙 更新时间:2023-11-03 20:10:08 25 4
gpt4 key购买 nike

我正在使用 this MSDN article 中给出的示例关于 DSACryptoServiceProvider 类。问题是每次运行代码时我都会得到不同的签名。

我尝试了 OpenSSL 并没有遇到这个问题,但这次我需要使用 System.Security.Cryptography。

这是一些源代码:

这是要签名的散列值

byte[] HashValue =
{
59, 4, 248, 102, 77, 97, 142, 201,
210, 12, 224, 93, 25, 41, 100, 197,
213, 134, 130, 135
};

这就是问题所在

 // The value to hold the signed value.
byte[] SignedHashValue1 = DSASignHash(HashValue, privateKeyInfo, "SHA1");
byte[] SignedHashValue2 = DSASignHash(HashValue, privateKeyInfo, "SHA1");

我使用调试器找出 SignedHashValue1 不等于 SignedHashValue2


文章代码:

using System;
using System.Security.Cryptography;

public class DSACSPSample
{
public static void Main()
{
try
{
DSAParameters privateKeyInfo;
DSAParameters publicKeyInfo;

// Create a new instance of DSACryptoServiceProvider to generate
// a new key pair.
using (DSACryptoServiceProvider DSA = new DSACryptoServiceProvider())
{
privateKeyInfo = DSA.ExportParameters(true);
publicKeyInfo = DSA.ExportParameters(false);
}

// The hash value to sign.
byte[] HashValue =
{
59, 4, 248, 102, 77, 97, 142, 201,
210, 12, 224, 93, 25, 41, 100, 197,
213, 134, 130, 135
};

// The value to hold the signed value.
byte[] SignedHashValue = DSASignHash(HashValue, privateKeyInfo, "SHA1");

// Verify the hash and display the results.
bool verified = DSAVerifyHash(HashValue, SignedHashValue, publicKeyInfo, "SHA1");

if (verified)
{
Console.WriteLine("The hash value was verified.");
}
else
{
Console.WriteLine("The hash value was not verified.");
}
}
catch (ArgumentNullException e)
{
Console.WriteLine(e.Message);
}
}

public static byte[] DSASignHash(byte[] HashToSign, DSAParameters DSAKeyInfo,
string HashAlg)
{
byte[] sig = null;

try
{
// Create a new instance of DSACryptoServiceProvider.
using (DSACryptoServiceProvider DSA = new DSACryptoServiceProvider())
{
// Import the key information.
DSA.ImportParameters(DSAKeyInfo);

// Create an DSASignatureFormatter object and pass it the
// DSACryptoServiceProvider to transfer the private key.
DSASignatureFormatter DSAFormatter = new DSASignatureFormatter(DSA);

// Set the hash algorithm to the passed value.
DSAFormatter.SetHashAlgorithm(HashAlg);

// Create a signature for HashValue and return it.
sig = DSAFormatter.CreateSignature(HashToSign);
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}

return sig;
}

public static bool DSAVerifyHash(byte[] HashValue, byte[] SignedHashValue,
DSAParameters DSAKeyInfo, string HashAlg)
{
bool verified = false;

try
{
// Create a new instance of DSACryptoServiceProvider.
using (DSACryptoServiceProvider DSA = new DSACryptoServiceProvider())
{
// Import the key information.
DSA.ImportParameters(DSAKeyInfo);

// Create an DSASignatureDeformatter object and pass it the
// DSACryptoServiceProvider to transfer the private key.
DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(DSA);

// Set the hash algorithm to the passed value.
DSADeformatter.SetHashAlgorithm(HashAlg);

// Verify signature and return the result.
verified = DSADeformatter.VerifySignature(HashValue, SignedHashValue);
}
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}

return verified;
}
}

最佳答案

如果您查看 DSA 的工作原理(例如 Wikipedia ),您会发现生成签名的第一步是选择一个随机值:

Generate a random per-message value k where 0 < k < q

稍后你会发现这种随机性是必要的:

With DSA, the entropy, secrecy, and uniqueness of the random signature value k is critical. It is so critical that violating any one of those three requirements can reveal the entire private key to an attacker. Using the same value twice (even while keeping k secret), using a predictable value, or leaking even a few bits of k in each of several signatures, is enough to break DSA.

随后提到了一个非常突出的破坏 ECDSA 的案例(它源自 DSA,但在椭圆曲线上工作)。

因此,您应该庆幸自己从未获得相同的签名。否则您的私钥将受到威胁。

关于c# - DSA 使用相同的数据生成不同的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20570625/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com