![](/img/trans.png)
[英]ECDSA signature with C# and Bouncy Castle does not match MS ECDsa signature
[英]Verifying ECDSA signature with Bouncy Castle in C#
當我嘗試在C#中驗證Bouncy Castle中的ECDSA簽名時,我遇到了問題。 代碼是從我擁有的Java示例中采用的,因此我100%確定公鑰和簽名是正確的。 但是C#實現總是返回簽名無效。 我檢查了曲線參數,它們是正確的。 我嘗試使用DER和“原始”簽名,但它再次無效。
任何人都可以發現我做錯了什么:
namespace TestECDSA
{
class Program
{
static void Main(string[] args)
{
byte[] b = new byte[] { 0x2B, 0xA1, 0x41, 0x00 };
string pubKey = "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF";
string signature = "AAD03D3D38CE53B673CF8F1C016C8D3B67EA98CBCF72627788368C7C54AA2FC4";
X9ECParameters curve = SecNamedCurves.GetByName("secp128r1");
ECDomainParameters curveSpec = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
ECPublicKeyParameters key = new ECPublicKeyParameters("ECDSA", curve.Curve.DecodePoint(Hex.Decode(pubKey)), curveSpec);
ISigner signer = SignerUtilities.GetSigner("NONEwithECDSA");
signer.Init(false, key);
signer.BlockUpdate(b, 0, b.Length);
if (signer.VerifySignature(derEncodeSignature(Hex.Decode(signature))))
System.Console.WriteLine("Verified Signature");
else
System.Console.WriteLine("Not Verified Signature");
}
public static byte[] derEncodeSignature(byte[] signature)
{
byte[] encoded = new byte[6 + signature.Length];
byte[] r = RangeSubset(signature, 0, 16);
byte[] s = RangeSubset(signature, 16, 16);
encoded[0] = 0x30;
encoded[1] = 0x24;
encoded[2] = 0x02;
encoded[3] = 0x10;
encoded[4 + r.Length] = 0x02;
encoded[5 + r.Length] = 0x10;
Array.Copy(r, 0, encoded, 4, r.Length);
Array.Copy(s, 0, encoded, 6 + r.Length, r.Length);
return encoded;
}
public static T[] RangeSubset<T>(T[] array, int startIndex, int length)
{
T[] subset = new T[length];
Array.Copy(array, startIndex, subset, 0, length);
return subset;
}
}
}
您可以使用signer.GenerateSignature(),而不是自己對簽名進行DER編碼:
var signerAlgorithm = "SHA256withECDSA";
ISigner signer = SignerUtilities.GetSigner(signerAlgorithm);
signer.Init(true, privateSigningKey);
signer.BlockUpdate(data, 0, data.Length);
byte[] signature = signer.GenerateSignature();
return signature;
dbugger是對的。 DER編碼錯了。 有問題的代碼應替換為:
private static byte[] derEncodeSignature(byte[] signature)
{
byte[] r = signature.RangeSubset(0, (signature.Length / 2));
byte[] s = signature.RangeSubset((signature.Length / 2), (signature.Length / 2));
MemoryStream stream = new MemoryStream();
DerOutputStream der = new DerOutputStream(stream);
Asn1EncodableVector v = new Asn1EncodableVector();
v.Add(new DerInteger(new BigInteger(1, r)));
v.Add(new DerInteger(new BigInteger(1, s)));
der.WriteObject(new DerSequence(v));
return stream.ToArray();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.