有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

雅加达ee Java Diffie hellman初始化ECDHKeyAgreement

我有一个Diffie–Hellman安全类,如下所示:

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 {
}

有时我需要重新初始化DHkeyAgreement

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

这是我的测试用例:

  1. 客户端初始化DH并生成公钥
  2. 客户端已将公钥发送到服务器
  3. 服务器使用客户端密钥初始化DH,并生成自己的公钥和共享密钥
  4. 服务器向客户端发送公钥
  5. 客户端使用服务器公钥生成共享密钥。 在此步骤中,客户端和服务器具有公钥和共享密钥

我的问题是client disconnected()和KeyAgreement由singleton对象初始化,并且不会再次重新初始化

有时候我需要做这个题目

请指导我解决这个问题


共 (1) 个答案

  1. # 1 楼答案

    这个IllegalStateException (Phase already executed)似乎特别是由SunEC提供者的ECDH实现引起的。如果在紧靠^{}之前执行(附加的)^{},则不会发生异常。但是,这个init调用应该是不必要的,因为在执行doPhase-call ^{}之后,至少根据generateSecret-文档,它应该将KeyAgreement-实例重置为init调用之后的状态:

    This method resets this KeyAgreement object to the state that it was in after the most recent call to one of the init methods...

    可能是SunEC提供程序中的错误。如果使用DH而不是ECDH(使用SunJCE提供程序而不是SunEC提供程序),则行为与预期一样,即可以重复doPhase-调用(无需额外的init-调用)。这同样适用于使用BouncyCastle-provider的ECDH。因此,您可以使用BouncyCastle提供程序而不是SunEC提供程序来使用代码运行ECDH

    注意:应将doPhase中的第二个参数(^{})设置为true,否则将生成IllegalStateException (Only two party agreement supported, lastPhase must be true)(至少对于ECDH)

    编辑:

    这个bug已经在JDK12中被发现并修复,请参见JDK-8205476: ^{} is not reset for ECDH based algorithmm