c#充气城堡验证签名上的InvalidCastException
Posted
技术标签:
【中文标题】c#充气城堡验证签名上的InvalidCastException【英文标题】:InvalidCastException on c# bouncy castle verify signature 【发布时间】:2013-04-12 08:45:04 【问题描述】:我尝试验证一个 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);
所以,签名似乎有问题,但我无法弄清楚。我希望任何人都可以提供一个好主意。
顺便说一下,这个例子中提供的数据被修改了,所以签名会被评估为假,如果它可以工作的话。
【问题讨论】:
你用的是什么版本的充气城堡? 您好,是c#版本的BouncyCastle.Crypto.dll,版本1.7.4114.6375 【参考方案1】:这可能为时已晚,但为了以后读者的利益:
DSA 签名应该是包含两个 INTEGER 的 SEQUENCE 的 ASN.1 编码。这里的问题是 b_signature 实际上是一个八位字节字符串,其中的八位字节是正确的编码。所以有一个额外的“外层”包裹着真实的签名。您可以通过转储结构来看到这一点:
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序列 整数(16446081942964531772961165410855935370418106604815444975891408706004345083361) 整数(87431453076334980518600256741994746667679967157867025465393185500427926877084)
因此,“内部”八位字节看起来已正确编码。现在:
bool valid = signer.VerifySignature(inner);
对我来说,这会打印“假”,您说这是预期的,因为数据已被修改。
【讨论】:
以上是关于c#充气城堡验证签名上的InvalidCastException的主要内容,如果未能解决你的问题,请参考以下文章