2015-12-08 3 views
2

Я пытаюсь создать протокол, который позволит клиенту отправить серверу его имя входа. После этого сервер получает пароль клиентов с сервера и создает из него ключ шифрования. Клиент создает ключ от введенного пароля. Таким образом я пытаюсь получить безопасное соединение.Переключение потока java для шифрования потока

Однако, после отправки имени пользователя, получения пароля и т. Д. Я пытаюсь создать новый objectinputstream из cypherstream для чтения данных, но он блокирует. Я не могу найти способ заставить его работать, даже посмотрев на многие другие подобные вопросы.

Serverside

private void switchToChipherStreams(String username) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException { 
    byte key[] = dbMediator.getPasswordCypher(username); 
    SecretKey key64 = new SecretKeySpec(key, "Blowfish"); 
    Cipher cipher = Cipher.getInstance("Blowfish"); 
    cipher.init(Cipher.ENCRYPT_MODE, key64); 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException ex) { 
     Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    out = new ObjectOutputStream(new CipherOutputStream(socket.getOutputStream(), cipher)); 
    out.reset(); 
    out.flush(); 
    out.writeObject("switch"); 
    in = new ObjectInputStream(new CipherInputStream(socket.getInputStream(), cipher)); 
} 

стороне клиента

private void switchToChipherStreams(String password) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException { 
    //Generate key 
    byte[] key = new byte[8]; 
    for (int i = 0; i < 8; i++) { 
     if (password.length() > i) { 
      key[i] = password.getBytes()[i]; 
     } else { 
      key[i] = (byte) i; 
     } 
    } 
    //Setup cipher streams 
    SecretKey key64 = new SecretKeySpec(key, "Blowfish"); 
    Cipher cipher = Cipher.getInstance("Blowfish"); 
    cipher.init(Cipher.ENCRYPT_MODE, key64); 
    in = new ObjectInputStream(new CipherInputStream(socket.getInputStream(), cipher)); 
    out = new ObjectOutputStream(new CipherOutputStream(socket.getOutputStream(), cipher)); 
    out.reset(); 
    out.flush(); 
    out.writeObject("switch"); 
} 

В данный момент это trowing исключение (неверный заголовок), потому что я пытаюсь отправить данные снова, но если я не просто блокирует.

Не мог бы кто-нибудь сказать мне, что я здесь делаю неправильно, или если это даже возможно изменить на зашифрованный objectinputstream.

С наилучшими пожеланиями,

Юр

EDIT

Измененный шифра для шифрования и дешифрования внутри и выходные потоки, новый код:

Serverside

byte key[] = dbMediator.getPasswordCypher(username); 
    SecretKey key64 = new SecretKeySpec(key, "Blowfish"); 
    Cipher cipheren = Cipher.getInstance("Blowfish"); 
    cipheren.init(Cipher.ENCRYPT_MODE, key64); 
    Cipher cipherde = Cipher.getInstance("Blowfish"); 
    cipheren.init(Cipher.DECRYPT_MODE, key64); 
    out = new ObjectOutputStream(new CipherOutputStream(socket.getOutputStream(), cipheren)); 
    out.reset(); 
    out.flush(); 
    out.writeObject("switch"); 
    in = new ObjectInputStream(new CipherInputStream(socket.getInputStream(), cipherde)); 

стороне клиента

//Generate key 
     byte[] key = new byte[8]; 
     for (int i = 0; i < 8; i++) { 
      if (password.length() > i) { 
       key[i] = password.getBytes()[i]; 
      } else { 
       key[i] = (byte) i; 
      } 
     } 
     //Setup cipher streams 
     SecretKey key64 = new SecretKeySpec(key, "Blowfish"); 
     Cipher cipheren = Cipher.getInstance("Blowfish"); 
     cipheren.init(Cipher.ENCRYPT_MODE, key64); 
     Cipher cipherde = Cipher.getInstance("Blowfish"); 
     cipheren.init(Cipher.DECRYPT_MODE, key64); 
     out = new ObjectOutputStream(new CipherOutputStream(socket.getOutputStream(), cipheren)); 
     out.reset(); 
     out.flush(); 
     out.writeObject("switch"); 
     in = new ObjectInputStream(new CipherInputStream(socket.getInputStream(), cipherde)); 

Теперь инвалиду проблема головы решена, но застывает как клиент и сервер, когда ObjectInputStream конструктор вызывается.

+0

Вам не нужно закрывать поток в какой-то момент? –

+0

Закрытие потока приводит к закрытию сокета –

+0

Как создать новую тему для каждого запроса клиента на стороне сервера? –

ответ

1

Вы не можете создать ввод шифрования и выходной поток от одного и того же объекта Cipher. Вам нужны два объекта Cipher, один в режиме DECRYPT и один в режиме ENCRYPT.

Создайте и промойте ObjectOutputStream перед ObjectInputStream с обоих концов.

+0

Я изменил шифры и создал объект outoutputstream с обеих сторон, а затем создавал objectinputstream, но он все же зависает при вызове конструктора objectinputstream. –

+0

Существуют шифры, где для шифрования и дешифрования используется один и тот же алгоритм. – zaph

+0

@zaph Конечно, есть. Я не сказал иначе. В эту категорию попало 99,999% потоковых шифров. Дело в том, что объекты 'Cipher' * *, которые не могут быть в двух режимах одновременно. – EJP

Смежные вопросы