c#bouncy castle验证签名的InvalidCastException

时间:2013-04-12 08:45:05

标签: c# bouncycastle signature ecdsa

我尝试验证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,如果它可以工作。

1 个答案:

答案 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',你说这是预期的,因为数据已被修改。