我正在尝试使用SpongyCastle验证Android上的ECDSA数字签名。我有一个didBeginContact
,其中包含我需要用来验证它的公钥,但我无法弄清楚如何使用X509Certificate
(向下转换PublicKey
)来使用ECPublicKey
班。
我使用C#版本的BouncyCastle完成了这个,看起来像这样:
ECDSASigner
在Java版本的API中,ECDsaSigner signer = new ECDsaSigner();
signer.Init(false, cert.GetPubliKey());
方法返回X509Certificate.getPublicKey()
类而不是PublicKey
。但是,AsymmetricKeyParameter
方法需要ECDSASigner.init()
个对象。我无法弄清楚如何为ECDSA做这件事。
对于RSA签名,我只是手动重建了一个新的CipherParameters
对象:
RSAKeyParameters
这似乎不太理想,但我认为它应该有效。但我甚至无法弄清楚如何为ECDSA做同样的事情。我认为有更好的方法可以做到这一点,但我无法弄清楚要使用的API。
答案 0 :(得分:4)
我想我终于搞清楚了。看起来我需要使用Signature
类来处理它,而不是直接使用ECDSASigner
类。我还是想了解ECDSASigner
类是如何在所有这些抽象内部使用的(仅仅是为了我自己的好奇心)。
无论如何,这是我的代码看起来像验证ECDSA签名(至少我的用途)。希望这将有助于一些未来的人试图解决类似的问题:
Signature sig = Signature.getInstance("NONEwithECDSA", "BC");
sig.initVerify(pubKey);
sig.update(plainBytes);
if (!sig.verify(signedBytes)) {
throw new Exception("ECDSA signature verification failed.");
}
答案 1 :(得分:0)
正如您自己所说,您需要使用Signature类。 JCA是在Java中执行加密的默认方式,它使用提供者模式:
Security.addProvider(new BouncyCastleProvider());
Android上的默认提供程序是一个简化的BouncyCastle。 SpongyCastle是BouncyCastle的全功能副本(为避免名称冲突而重命名)。还有Sun / Oracle JCA可用。
Signature sig = Signature.getInstance("NONEwithECDSA", "BC");
此处,JCA查找名称为“BC”的提供程序,以及是否已注册支持“NONEwithECDSA”签名的SignatureSpi类。 “Signature”类用作工厂类,它也包装实际的实现类。
sig.initVerify(pubKey);
首先,它在Signature类中执行一些代码(通常只是验证),然后调用底层的SignatureSpi类。当您尝试直接使用提供程序时,此中间层可能是缺少的,例如,类初始化可能需要额外的步骤。
要查看更多详细信息,您可以下载弹性/海绵城堡源并在调试器中执行示例 - 这不是特定于Android的,因此您可以在Eclipse中创建桌面应用程序。