如何在Java中将CipherInputStream和CipherOutputStream转换为ObjectInputStream和ObjectOutputStream?

时间:2014-09-14 19:02:03

标签: java networking encryption network-programming

我正在编写加密的服务器/客户端系统,我需要能够通过网络加密对象(数据包)。我的问题涉及从CipherInput和Output Streams创建ObjectOutput和Input流。

首先,(在客户端),当我创建我的ObjectInputStream时,它只是挂在那里:

    public void connectToServer(String serverIP, int port)
    {
    try 
    {
        socket = new Socket(serverIP, port);                                
        key = KeyGeneratorWrapper.getEncryptionKey();                       // KeyGen
        encryptedSocket = new SecretSocket(socket, key);
        out = new ObjectOutputStream(encryptedSocket.getOutputStream());    
        in = new ObjectInputStream(encryptedSocket.getInputStream());   // HANGS HERE   
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
}

其次,(如果我在客户端注释掉输入流),当我实际上从客户端向服务器发送对象时,服务器会一直等待通过以下方式发送对象:

            Socket socket = null;   // Client's Socket
            socket = serverSocket.accept();                                          // Wait for a new connection
            key = KeyGeneratorWrapper.getEncryptionKey();                            // Get key for encryption/decryption
            encryptedSocket = new SecretSocket(socket, key);                        // Create secure communication path to receive/send data on
            out = new ObjectOutputStream(encryptedSocket.getOutputStream());        // Get the output stream
            in = new ObjectInputStream(encryptedSocket.getInputStream());           // Get the input stream for client socket

            Packet clientDetails = null;

            clientDetails = (Packet)(in.readObject());// SERVER WAITS HERE
            System.out.println("Received");

请注意,“encryptedSocket”会返回CipherOutput和Input Streams

以下是“SecretSocket”的代码:

public class SecretSocket
{
private Key key;                        // Encryption key
private Cipher inCipher;                // Decryption Cipher
private Cipher outCipher;               // Encryption Cipher
private CipherInputStream in;           // Cipher incoming data
private CipherOutputStream out;         // Cipher outgoing data

private Socket socket;                  // UNSAFE COMMUNICATION SOCKET

public static String ALGORITHM = "DES"; // Encryption algorithm
private String currentAlgorithm;        // Current encryption algorithm being used

public SecretSocket(Socket s, Key key)
{
    this.key = key;
    socket = s;
    currentAlgorithm = ALGORITHM;
    initialize();
}

/**
 * Create encryption and decryption ciphers
 * @param input
 */
public void initialize()
{
       try 
       {
            outCipher = Cipher.getInstance(currentAlgorithm);
            outCipher.init(Cipher.ENCRYPT_MODE, key);
            inCipher = Cipher.getInstance(currentAlgorithm);
            inCipher.init(Cipher.DECRYPT_MODE, key);
        }
        catch (NoSuchAlgorithmException e) 
        {
            e.printStackTrace();
        }
        catch (NoSuchPaddingException e) 
        {
            e.printStackTrace();
        }
        catch (InvalidKeyException e) 
        {
            e.printStackTrace();
        }
}

/**
 * Return incomming datastream
 * @param input
 */
public InputStream getInputStream()
{
    InputStream is = null;
    try 
    {
        is = socket.getInputStream();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
    in = new CipherInputStream(is, inCipher);
    return in;
}

/**
 * Return outgoing datastream
 * @param input
 */
public OutputStream getOutputStream()
{
    OutputStream os = null;
    try 
    {
        os = socket.getOutputStream();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
    out = new CipherOutputStream(os, outCipher);
    return out;
}

}

2 个答案:

答案 0 :(得分:1)

像这样:

CipherInputStream cis = new CipherInputStream(socket.getInputStream, inCipher);
ObjectInputStream ois = new ObjectInputStream(cis);

答案 1 :(得分:-1)

创建后需要刷新ObjectOutputStream。否则,对等体将在new ObjectInputStream(...)处阻止。这并非总是如此,但是当存在潜在的缓冲流或密码流时就是这样。