Java中的Socket和ObjectInputStream - Android

时间:2014-08-24 06:53:01

标签: java android security encryption objectinputstream

我使用Cipher类的Java遇到了Socket和ObjectInputStream的问题。 我使用客户端Android,在Socket上编写ObjectOutputStream,以及从同一个Socket读取此ObjectInputStream的客户端Java。 这是代码客户端/服务器

客户端

[CODE]

 public static void functionRegistration(String usr, String pwd) throws UnknownHostException, IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{

    Socket socket = new Socket(SERVER_ADDRESS_STRING, PORT_NO);
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    socket.setSoTimeout(DEFAULT_TIMEOUT);

    if(!socket.isConnected()){
        System.out.println("[!] [Client] Connection problem!");
        socket.close();
        return;
    }

    //Diffie-Hellman
    BigInteger shared_key = DiffieHellmanExchangeClient(socket, br, bw);
    byte[] hash = ObjectHash.getByteHashCode(shared_key, SECURE_HASH_TYPE.SHA384);

    //Extract IV and cipherKey
    byte[] IV = new byte[16];
    byte[] cipherKey = new byte[32];

    int i, limit;

    for(i = 0; i < IV.length; i++)
        IV[i] = hash[i];

    limit = i;

    for(; i < hash.length; i++)
        cipherKey[i - limit] = hash[i];

    //Send username
    bw.write(usr);
    bw.write("\r\n");
    bw.flush();


    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());

    //Hash password
    String passwordHash = new String(ObjectHash.getByteHashCode(pwd, SECURE_HASH_TYPE.SHA512));

    //Cipher password
    String encryptedPasswordHash = new String(cipherMessage(passwordHash, cipherKey));

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec ivparameters = new IvParameterSpec(IV);
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(cipherKey, "AES"), ivparameters);


    oos.writeObject(new SealedObject(encryptedPasswordHash, cipher));
    oos.flush();


    if(br.readLine().compareTo("ACK") == 0)
        Log.d("ACK", "ACK_RECEIVED");

    else
        Log.d("ACK","Something was wrong");

    br.close();
    bw.close();
    socket.close();
}

[\ CODE]

SERVER

[CODE]

  private void getRegistrationUser() throws IOException, InvalidKeyException, InvalidAlgorithmParameterException{
    String username = br.readLine();

    System.out.println("[+] [Server - Thread " + Thread.currentThread().getId() + "] Username received");

    //SHA384 of shared key
    byte[] hash = ObjectHash.getByteHashCode(shared_key, SECURE_HASH_TYPE.SHA384);

    byte[] IV = new byte[16];
    byte[] cipherKey = new byte[32];

    int j, limit;

    for(j = 0; j < IV.length; j++)
        IV[j] = hash[j];

    limit = j;

    for(; j < hash.length; j++)
        cipherKey[j - limit] = hash[j];

    try{

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivparameters = new IvParameterSpec(IV);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cipherKey, "AES"), ivparameters);

        ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
        String encryptedHashPassword = (String)((SealedObject)ois.readObject()).getObject(cipher);

        String decryptedHashPassword = decipherMessage(encryptedHashPassword, cipherKey);

        ois.close();

        sendACK();

    }
    catch (IOException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    }   
}

[\ CODE]

代码cipherMessage和decipherMessage中的两个函数使用Twofish Cipher来使用相应的密钥加密和解密数据

问题在于:我在调试阶段注意到服务器在newObjectInputStream上阻塞,并且读取客户端写入的对象是不可能的

如何解决我的问题?

1 个答案:

答案 0 :(得分:1)

您无法在同一套接字上使用多个缓冲流。他们会互相窃取数据。使用对象流来处理所有事情。