2

我尝试验证 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);

所以,签名似乎有问题,但我无法弄清楚。我希望任何人都可以提供一个好主意。

顺便说一句,此示例中提供的数据已被修改,因此签名将被评估为假,如果它可以工作的话。

4

1 回答 1

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 八位组字符串[71]

DER Sequence Integer(16446081942964531772961165410855935370418106604815444975891408706004345083361) Integer(87431453076334980518600256741994746667679967157867025465393185500427926877084)

因此,“内部”八位字节看起来被正确编码。现在:

bool valid = signer.VerifySignature(inner);

对我来说,这会打印“假”,您说这是预期的,因为数据已被修改。

于 2013-06-24T12:00:59.380 回答