Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ObjectInputStream与CipherInputStream冻结、挂起_Java_Encryption_Stream_Streaming_Jca - Fatal编程技术网

Java ObjectInputStream与CipherInputStream冻结、挂起

Java ObjectInputStream与CipherInputStream冻结、挂起,java,encryption,stream,streaming,jca,Java,Encryption,Stream,Streaming,Jca,我正在编写基于客户机-服务器的Java应用程序,我遇到了一个问题,因为在客户机和服务器中构造ObjectInputStream时,它会挂起 客户: Socket socket = new Socket("localhost", 9999); outCiph = new CipherOutputStream(socket.getOutputStream(), AES.getEncryptCipher("key")); out = new ObjectOutputStream(outCiph);

我正在编写基于客户机-服务器的Java应用程序,我遇到了一个问题,因为在客户机和服务器中构造ObjectInputStream时,它会挂起

客户:

Socket socket = new Socket("localhost", 9999);

outCiph = new CipherOutputStream(socket.getOutputStream(), AES.getEncryptCipher("key"));
out = new ObjectOutputStream(outCiph);
inCiph = new CipherInputStream(socket.getInputStream(), AES.getDecryptCipher("key"));
in = new ObjectInputStream(inCiph);

try
{
String text = "test!";

out.writeObject(text);
out.flush();

if (out != null)
out.close();

if (in != null)
in.close();
}
catch (IOException ex)
{
System.err.println(ex.toString());
}
服务器:

ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();

outCiph = new CipherOutputStream(socket.getOutputStream(), AES.getEncryptCipher("key"));
out = new ObjectOutputStream(outCiph);
inCiph = new CipherInputStream(socket.getInputStream(), AES.getDecryptCipher("key"));
in = new ObjectInputStream(inCiph);

try
{
String rec = (String) in.readObject();
System.out.println("Received from client: " + rec);

if (out != null)
out.close();

if (in != null)
in.close();

}
catch (IOException ex)
{
System.err.println(ex.toString() + " in start()");
}
catch (ClassNotFoundException ex)
{
System.err.println(ex.toString());
}
AES:

//我不是generateKey方法的作者,所以我不知道它是否正确
私有静态字节[]generateKey(字符串传递)引发不受支持的编码异常,NoSuchAlgorithmException
{
MessageDigest sha=MessageDigest.getInstance(“sha-256”);
byte[]passBytes=pass.getBytes(“ASCII”);
字节[]sha256Bytes=sha.digest(passBytes);
字节[]键=新字节[16];
int j=0;
for(int i=0;i

当我不使用CipherInput/OutputStream时,一切正常,因此问题在某种程度上与CipherInput/OutputStream有关。

只有在发送完所有信息后才需要创建ObjectInputStream,因为ObjectInputStream的构造函数会阻塞,因为它需要读取头


通常,所有字节都会被ObjectOutputStream写入,但现在CipherOutputStream在发送(最后一部分)报头之前等待,直到它拥有完整的16字节块(对于AES)。流密码模式(CTR或GCM)中的AES在这里可能更有用,因为它使用每字节加密,并且能够直接发送每个字节。

只有在发送完所有信息后,您才需要创建ObjectInputStream,因为ObjectInputStream的构造函数会阻塞,因为它需要读取头


通常,所有字节都会被ObjectOutputStream写入,但现在CipherOutputStream在发送(最后一部分)报头之前等待,直到它拥有完整的16字节块(对于AES)。在这里,流密码模式(CTR或GCM)中的AES可能更有用,因为它使用每字节加密,并且能够直接发送每个字节。

DES.getEncryptCipher返回什么类型的密码?你能打印出返回密码的算法和状态吗?可能您需要一个执行填充的密码,否则它可能正等待N*[块大小]字节来完成计算。注意DES是不安全的,使用AESDES只是一个例子,我正在测试另一个类。主加密类是上面的一个,不是DES.Ok,但一定要对密码使用
“AES/CBC/PKCS5Padding”
,就像
“AES”
默认为
“AES/ECB/PKCS5Padding”
,至少对于Sun/Oracle提供程序是这样,ECB对于头和对象等非随机字节是不安全的。DES.getEncryptCipher返回什么类型的密码?你能打印出返回密码的算法和状态吗?可能您需要一个执行填充的密码,否则它可能正等待N*[块大小]字节来完成计算。注意DES是不安全的,使用AESDES只是一个例子,我正在测试另一个类。主加密类是上面的一个,不是DES。好的,但一定要对密码使用
“AES/CBC/PKCS5Padding”
,因为
“AES”
默认为
“AES/ECB/PKCS5Padding”
,至少对Sun/Oracle提供程序是这样,ECB对于头和对象等非随机字节是不安全的。您可以执行一些黑客操作,例如,在创建构造函数后直接写入字节数组,然后刷新ObjectOutputStream。当然,你也需要从另一端读取那些虚假的16字节。如果你继续回答你的问题,用户1227115,或者点击“接受”按钮,那就太好了。你可以执行一些黑客操作,比如在创建构造函数后直接写一个字节数组,然后刷新ObjectOutputStream。当然,您还需要读取另一端的伪16字节。如果您继续回答您的问题(用户1227115),或者点击“接受”按钮,那将是一件好事。
// I'm not author of generateKey method so I've no idea if is it correct
private static byte[] generateKey(String pass) throws UnsupportedEncodingException, NoSuchAlgorithmException
{
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] passBytes = pass.getBytes("ASCII");
byte[] sha256Bytes = sha.digest(passBytes);


byte[] key = new byte[16];
int j = 0;
for (int i = 0; i < sha256Bytes.length; i++)
{
    if (i % 2 == 0)
    {
    key[j] = sha256Bytes[i];
    j++;
    }
}
return key;
}

public static Cipher getEncryptCipher(String pass)
{
try
{
    SecretKeySpec skeySpec = new SecretKeySpec(generateKey(pass), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    return cipher;
}
catch (Exception ex) // just for clarity
{
    Logger.getLogger(AES.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

public static Cipher getDecryptCipher(String pass)
{
try
{
    SecretKeySpec skeySpec = new SecretKeySpec(generateKey(pass), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    return cipher;
}
catch (Exception ex) // just for clarity
{
    Logger.getLogger(AES.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}