我正在构建一个使用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 Key类型,但我认为这两个代表了关于曲线上的点的相同内容 - 或者我对它背后的理论完全错了?
我问的原因是现在我的应用程序使用ECDH罚款来建立AES密钥,但现在我想使用相同的EC密钥来使用ECDSA对每条消息进行签名。
答案 0 :(得分:25)
ECDSA和ECDH来自不同的标准(分别为ANSI X9.62和X9.63),并用于不同的上下文中。 X9.63显式地重用了X9.62中的元素,包括公钥的标准表示(例如在X.509证书中)。因此,ECDSA和ECDH密钥对在很大程度上是可互换的。然而,给定的实施是否允许这种交换是一个悬而未决的问题。从历史上看,(EC)DSA和(EC)DH来自不同的世界。
但请注意,使用情境非常明显。密码学比椭圆曲线上的计算要多一些;必须考虑“关键生命周期”。简单来说,您不希望使用相同的过程管理密钥协商密钥和签名密钥。例如,如果您丢失了密钥协议密钥(您的狗吃掉了智能卡 - 不要笑,它确实发生了),那么您就不能再解密相对于该密钥加密的数据(例如发送给您的加密电子邮件,以及以加密格式存储)。从商业角度来看,丢失钥匙也可能是员工的损失(员工被解雇,被公共汽车撞击,或退休,或其他任何事情)。因此,加密密钥(包括密钥协商密钥)必须经常被托管(例如,私钥的副本被打印并存储在保险箱中)。另一方面,丢失签名密钥意味着没有数据丢失;以前签发的签名仍可以验证;从这种损失中恢复就像创建新密钥对一样简单。但是,托管系统的存在往往会自动删除可能附加在其上的任何合法价值的签名。
另外,在更一般的基础上,我强烈建议不要在两种不同的算法中使用相同的私钥:算法之间的交互尚未完全探索(简单地研究一种算法已经很难)。例如,如果某人开始使用从您使用相同私钥计算的ECDSA签名中提取的曲线点开始提供基于ECDH的协议,会发生什么?
所以你真的不应该为ECDH和ECDSA重复使用相同的密钥。