我有一个像这样的迪夫-赫尔曼保安班:
public class AESSecurityCap {
private PublicKey publicKey;
KeyAgreement keyAgreement;
byte[] sharedsecret;
AESSecurityCap() {
makeKeyExchangeParams();
}
private void makeKeyExchangeParams() {
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(128);
KeyPair kp = kpg.generateKeyPair();
publicKey = kp.getPublic();
keyAgreement = KeyAgreement.getInstance("ECDH");
keyAgreement.init(kp.getPrivate());
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
}
public void setReceiverPublicKey(PublicKey publickey) {
try {
keyAgreement.doPhase(publickey, false); // <--- Error on this line
sharedsecret = keyAgreement.generateSecret();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
}
并实现了这个类:
public class Node extends AESSecurityCap {
}
有时我需要重新初始化DH keyAgreement
:
public class TestMainClass {
public static void main(String[] args) {
Node server = new Node();
Node client = new Node();
server.setReceiverPublicKey(client.getPublicKey());
client.setReceiverPublicKey(server.getPublicKey());
// My problem is this line ,
// Second time result exception
server.setReceiverPublicKey(client.getPublicKey());
}
}
但请接受这一例外:
Exception in thread "main" java.lang.IllegalStateException: Phase already executed
at jdk.crypto.ec/sun.security.ec.ECDHKeyAgreement.engineDoPhase(ECDHKeyAgreement.java:91)
at java.base/javax.crypto.KeyAgreement.doPhase(KeyAgreement.java:579)
at ir.moke.AESSecurityCap.setReceiverPublicKey(AESSecurityCap.java:37)
at ir.moke.TestMainClass.main(TestMainClass.java:13)
有什么方法可以多次重新初始化ECDH KeyAgreement吗?
这是我的测试用例:
我的问题是客户端断开连接()和由单例对象初始化的KeyAgreement,而不是第二次重新初始化。
有时候我需要做这件事。
请指导我解决这个问题。
发布于 2019-09-15 06:24:09
IllegalStateException (Phase already executed)
似乎特别是由SunEC提供商的ECDH实现引起的.如果在紧接init
之前执行(附加的) doPhase
,则不会出现异常。但是,这个init
-call不应该是必要的,因为在执行doPhase
-call generateSecret
之后,应该将KeyAgreement
-instance重置为init
-call之后的状态,至少根据generateSecret
-documentation:
此方法将此KeyAgreement对象重置为它在最近调用init方法之一后所处的状态.
可能是SunEC提供商的一个漏洞。如果使用DH代替ECDH (并且使用SunJCE-provider而不是SunEC-provider),则行为是预期的,即可以重复使用doPhase
-calls (不需要额外的init
-calls)。这同样适用于使用BouncyCastle-provider的ECDH。因此,您可以使用BouncyCastle代替SunEC-provider来使用您的代码运行ECDH。
注意:第二个参数(lastPhase
在doPhase
中应该设置为true,否则将生成一个IllegalStateException (Only two party agreement supported, lastPhase must be true)
(至少对于ECDH)。
编辑:
在JDK 12中已经知道并修复了这个bug,请参阅不重置基于ECDH的算法。。
https://stackoverflow.com/questions/57943056
复制相似问题