【发布时间】:2015-12-08 09:25:42
【问题描述】:
我正在尝试创建一个协议,让客户端向服务器发送它的登录名。在此之后,服务器从服务器获取客户端密码并从中创建一个密码密钥。客户端根据输入的密码创建一个密钥。通过这种方式,我正在尝试建立安全连接。
但是,在发送用户名、获取密码等之后。我试图从 cypherstream 创建一个新的 objectinputstream 来读取数据,但它会阻塞。即使看了很多其他类似的问题,我也找不到让它工作的方法。
服务器端
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");
}
目前它正在抛出异常(无效标头),因为我正在尝试发送数据,但如果我不这样做,它只会阻塞。
谁能告诉我我在这里做错了什么,或者是否有可能更改为加密的对象输入流。
亲切的问候,
朱尔
编辑
更改密码以加密和解密输入和输出流,新代码:
服务器端
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 构造函数时会冻结客户端和服务器。
【问题讨论】:
-
你不需要在某个时候关闭流吗?
-
关闭流导致关闭套接字
-
在服务器端为每个客户端请求创建一个新线程怎么样?
-
对于每个连接到服务器的客户端,我正在创建一个新线程。用户发送它的用户名,服务器从数据库获取密码并从密码创建一个密钥,客户端也是如此。如果客户端输入了错误的密码,则流将失败。但是,我必须进行切换。但是当我没有立即向它发送东西时,它会在创建新的 objectinputstream 时冻结。当我发送一些东西时,我得到一个无效的头部异常。
标签: java sockets encryption objectinputstream