我尝试验证ecdsa(256)签名,我必须做的唯一数据是下面给定格式的公钥,原始数据和签名:
string pubKey_ecdsa = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+noecsW+vdfd8DNo5dsAxU4DOaNt6PGmSCLFo/EvQG4xmVzv464qXvDPIrPN8GtLnubzoa9rtWJD52VlGOpFsA==";
string data_ecdsa = ";\"4399901526945\";\"AAAA-BBBBBBBBB-123456789000\";\"5010112544615\";\"20130802063109143\";";
string signature_ecdsa = @"BEcwRQIgJFwnCvm8lRjlRt+G+f4viJktDYVyOiXUd5BJ0V761eECIQDBTHLjJI7KK3FhczEHjunenYWXylDdW91jbS23EmeznA==";
当我尝试使用充气城堡通过调用来验证签名时:
//Create the public key from string
AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(Convert.FromBase64String(pubKey_ecdsa));
// create byte array from string
byte[] b_signature = Convert.FromBase64String(signature_ecdsa);
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] inputData = encoder.GetBytes(data_ecdsa);
ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
signer.Init(false, pubKey);
signer.BlockUpdate(inputData, 0, inputData.Length);
bool valid = signer.VerifySignature(b_signature);
我收到了InvalidCastException
:
Unable to cast object of type 'Org.BouncyCastle.Asn1.DerOctetString'
to type 'Org.BouncyCastle.Asn1.Asn1Sequence'.
在以下行:
bool valid = signer.VerifySignature(b_signature);
所以,签名似乎有些不对劲,但我无法弄明白。我希望任何人都可以提出一个好主意。
顺便说一下,此示例中提供的数据已被修改,因此签名将被评估为false,如果它可以工作。
答案 0 :(得分:3)
这可能为时已晚,无法为后来的读者带来好处:
DSA签名应该是包含两个INTEGER的SEQUENCE的ASN.1编码。这里的问题是b_signature实际上是一个OCTET STRING,其中的八位字节是正确的编码。因此真正的签名周围有一个额外的“外部”包裹。您可以通过转储结构来看到这一点:
Asn1OctetString outer =(Asn1OctetString)Asn1Object.FromByteArray(b_signature);
byte[] inner = outer.GetOctets();
Console.WriteLine(Asn1Dump.DumpAsString(outer));
Console.WriteLine(Asn1Dump.DumpAsString(Asn1Object.FromByteArray(inner)));
对我来说,打印:
DER Octet String [71]
DER序列 整型(16446081942964531772961165410855935370418106604815444975891408706004345083361) 整数(87431453076334980518600256741994746667679967157867025465393185500427926877084)
因此,“内部”八位字节看起来是正确编码的。现在:
bool valid = signer.VerifySignature(inner);
对我来说,这会打印'false',你说这是预期的,因为数据已被修改。