繁体   English   中英

如何在其他两种类型的流中使用Socket流-Java

[英]How to use Socket stream in two other types of Streams - Java

我正在尝试为Java实现Diffie-Hellman的握手。 我有一个小问题,Diffie-Hellman是通过将DataInputStream和DataOutputStream与客户端的Socket一起使用来完成的,但是为了使用它返回的秘密,我需要使用CipherStream。 所以我在套接字上使用了CipherStream和DataStream。

public byte[] DHHandshake(Socket s){
        byte[] secret = null;
        try (DataOutputStream out = new DataOutputStream(s.getOutputStream())){
            try(DataInputStream in = new DataInputStream(s.getInputStream())){
                //Crear llave pública y privada en el cliente.
                KeyPairGenerator kpg = KeyPairGenerator.getInstance(PROTOCOL);
                kpg.initialize(Skip.sDHparameterSpec);
                KeyPair keyPair = kpg.generateKeyPair();

                //Envía llave pública del cliente al servidor
                byte[] keyBytes = keyPair.getPublic().getEncoded();
                out.writeInt(keyBytes.length);
                out.write(keyBytes);

                //Recibe llave pública del servidor
                keyBytes = new byte[in.readInt()];
                in.readFully(keyBytes);
                KeyFactory kf = KeyFactory.getInstance(PROTOCOL);
                X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(keyBytes);
                PublicKey theirPublicKey = kf.generatePublic(x509Spec);

                //Llave pública servidor + llave privada cliente = llave compartida.
                KeyAgreement ka = KeyAgreement.getInstance(PROTOCOL) ;
                ka.init(keyPair.getPrivate());
                ka.doPhase(theirPublicKey, true);
                secret = ka.generateSecret();
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
        return secret;
    }

try-with-resources关闭数据流,但也关闭Socket。 因此,当我尝试使用DiffieHellman中返回的机密通过CipherStream发送文件时,它将引发异常,表明套接字已关闭:

private void receiveFile(Socket s, byte[] secret){
        try(FileOutputStream fileWriter = new FileOutputStream(FILE)){
            Cipher cipher = Cipher.getInstance(ALGORITHM + "/ECB/PKCS5PADDING");
            SecretKeySpec keySpec = new SecretKeySpec(secret, ALGORITHM); 
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            try(CipherInputStream cipherIn = new CipherInputStream(s.getInputStream(), cipher)){
                byte[] fileBuffer = new byte[1024];
                int len;
                while ((len = cipherIn.read(fileBuffer)) >= 0)
                    fileWriter.write(fileBuffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
        //TODO checkMD5
    }

所以这是我的问题:

  • 如果我不关闭DataStream,那么有可能重新使用SocketStream发送数据。 因为DataStream和CipherStream同时使用它,这不会损坏SocketStream吗?

  • 有没有一种方法可以不关闭SocketStream而关闭DataStream?

  • 有没有一种方法可以使用DataStream初始化CipherStream? 喜欢重复使用吗?

所有这些的简单答案是将密码流包装在各自的数据流周围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM