15

我正在构建一个使用 BouncyCastle 作为密码提供者的网络应用程序。假设您有这个来生成密钥对:

ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("prime192v1");
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
g.initialize(ecSpec, new SecureRandom());
KeyPair pair = g.generateKeyPair();

我很困惑为什么你会得到一个ECDSA KeyPairGenerator 的实例。为什么不只是说EC?我知道 BouncyCastle 附带了一个 ECDH 密钥类型,但我认为这两者代表了关于曲线上点的相同内容——或者我完全错了它背后的理论?

我问的原因是,现在我的应用程序很好地使用 ECDH 来建立 AES 密钥,但现在我想使用相同的 EC 密钥来使用 ECDSA 对每条消息进行签名。

4

1 回答 1

32

ECDSA 和 ECDH 来自不同的标准(分别为 ANSI X9.62 和 X9.63),并在不同的上下文中使用。X9.63 明确地重用了来自 X9.62 的元素,包括公钥的标准表示(例如在 X.509 证书中)。因此,ECDSA 和 ECDH 密钥对在很大程度上是可互换的。然而,给定的实现是否允许这种交换是一个悬而未决的问题。从历史上看,(EC)DSA 和 (EC)DH 来自不同的世界。

但请注意,使用上下文是截然不同的。密码学比椭圆曲线上的计算要多一些。必须考虑“密钥生命周期”。简而言之,您不希望使用相同的过程来管理密钥协商密钥和签名密钥。例如,如果您丢失了您的密钥协议密钥(您的狗吃掉了您的智能卡——别笑,这确实发生了),那么您将无法再解密相对于该密钥加密的数据(例如,发送给您的加密电子邮件,以及以加密格式存储)。从业务的角度来看,丢失钥匙也可能是员工的损失(员工被解雇,被公共汽车撞倒,或退休,或其他)。因此,加密密钥(包括密钥协议密钥)必须经常被托管(例如,私钥的副本被打印并存储在保险箱中)。另一方面,签名密钥的丢失意味着没有数据丢失;以前签发的签名仍然可以验证;从这种损失中恢复就像创建一个新的密钥对一样简单。然而,托管系统的存在往往会自动剥离任何可能附加在其上的合法价值的签名。

此外,在更一般的基础上,我强烈建议不要在两种不同的算法中使用相同的私钥:算法之间的交互还没有被充分探索(仅仅研究一种算法已经很辛苦了)。例如,如果有人开始向您的基于 ECDH 的协议提供从您使用相同私钥计算的 ECDSA 签名中提取的曲线点,会发生什么?

所以你真的不应该为 ECDH 和 ECDSA 重复使用相同的密钥。

于 2011-02-11T15:13:00.527 回答