ECDH 和 ECDSA 密钥之间有区别吗?

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

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

我很困惑为什么你会得到一个ECDSA KeyPairGenerator的实例。为什么它不直接说EC?我知道有一个 ECDH Key 类型随 BouncyCastle 一起提供,但我认为这两者代表了关于曲线上点的相同内容 - 或者我对它背后的理论完全错误?

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


答案 1

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

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

此外,在更一般的基础上,我强烈建议不要在两种不同的算法中使用相同的私钥:算法之间的相互作用尚未得到充分探索(简单地研究一种算法已经很辛苦了)。例如,如果有人开始使用从您使用相同私钥计算的ECDSA签名中提取的曲线点来馈送基于ECDH的协议,会发生什么情况?

因此,您真的不应该为ECDH和ECDSA重用相同的密钥。


答案 2