使用C#中的Bouncy CastlevalidationECDSA签名

当我尝试在C#中validationBouncy 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[] 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(); }