使用海绵城堡验证ECDSA签名



我正在尝试使用海绵城堡验证Android上的ECDSA数字签名。我有一个X509Certificate,其中包含我需要用来验证它的公钥,但我不太清楚如何获得PublicKey(向下投射ECPublicKey)用于ECDSASigner类。

我使用c#版本的BouncyCastle完成了这一点,它看起来像这样:

ECDsaSigner signer = new ECDsaSigner();
signer.Init(false, cert.GetPubliKey());

在Java版本的api中,X509Certificate.getPublicKey()方法返回PublicKey类而不是AsymmetricKeyParameter。然而,ECDSASigner.init()方法需要一个CipherParameters对象。我不知道如何为ECDSA做这件事。

对于RSA签名,我只是手动重建了一个新的RSAKeyParameters对象:

RSAEngine engine = new RSAEngine();
engine.init(
    false,
    new RSAKeyParameters(
        false,
        ((RSAPublicKey) pubKey).getModulus(),
        ((RSAPublicKey) pubKey).getPublicExponent()
    )
);

这似乎不理想,但我认为它应该工作。但我甚至不知道如何对ECDSA进行等价处理。我认为有更好的方法来做到这一点,但我不能找出正确的api使用

我想我终于弄明白了。看起来我需要使用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.");
}

正如您自己注意到的,您需要使用Signature类。JCA是Java中默认的加密方式,它使用提供者模式:

    首先,你必须注册要使用的提供商,例如
<>以前安全。addProvider(新BouncyCastleProvider()); 之前

Android上的默认提供商是一个精简的BouncyCastle。海绵城堡是一个功能齐全的复制BouncyCastle(重命名以避免名称冲突)。还有Sun/Oracle的JCA。

  • 下一步,请求签名实例,例如:
  • Signature sig =签名。getInstance("NONEwithECDSA"、"公元前");之前

    这里,JCA查找名称为"BC"的提供程序,以及它是否注册了一个支持"NONEwithECDSA"签名的SignatureSpi类。"Signature"类作为工厂类工作,它也包装了实际的实现类。

    最后,您可以使用签名实例:<>以前sig.initVerify (pubKey); 之前

    首先,它在Signature类中执行一些代码(通常只是验证),然后调用底层的SignatureSpi类。当你试图直接使用提供程序时,这个中间层可能是缺失的,例如,类初始化可能需要额外的步骤。

    要查看更多细节,您可以下载bouncy/sponge castle源代码并在调试器中执行示例-这不是android特定的,因此您可以,例如,在Eclipse中创建桌面应用程序

    相关内容

    • 没有找到相关文章

    最新更新