简体   繁体   English

Java中的Socket和ObjectInputStream-Android

[英]Socket and ObjectInputStream in Java - Android

I have a problem with the Socket and ObjectInputStream using the Cipher class of Java. 使用Java的Cipher类时,Socket和ObjectInputStream出现问题。 I use a client Android, that write an ObjectOutputStream on Socket, and a client Java that read this ObjectInputStream from the same Socket. 我使用一个客户端Android,该客户端在Socket上编写一个ObjectOutputStream,以及一个客户端Java,该Java从同一Socket读取此ObjectInputStream。 This is the code client/server 这是客户端/服务器代码

CLIENT 客户

[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] [\\码]

The two functions in the code cipherMessage and decipherMessage use a Twofish Cipher for encrypt and decrypt data with the respectively key 代码cipherMessage和decipherMessage中的两个函数使用Twofish密码来分别使用密钥加密和解密数据

The problem is that: I note in debug phase that the server is blocking on newObjectInputStream and it is impossibilitate to read the object written by client 问题是:我在调试阶段注意到服务器在newObjectInputStream上阻塞,并且不可能读取客户端编写的对象

How can I solve my problem? 我该如何解决我的问题?

You can't use multiple buffered streams on the same socket. 您不能在同一套接字上使用多个缓冲流。 They will steal data from each other. 他们将互相窃取数据。 Use the object streams for everything. 使用对象流进行所有操作。

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

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