通过java.io.FilterInputStream和java.io.FFilterOutputStream加密



我在Java程序中使用了FilterInputStream和FilterOutputStream来更好地控制对象数据的传入和传出流,以便在对象大小溢出时抛出错误,手动启用/禁用加密,而无需创建新的ObjectOutputStream或需要客户端重新连接。我已经为密钥交换实现了Diffie-hellman的算法,但当通过密钥(客户端和服务器之间的共享密钥(移动字节时,我从另一方的ObjectInputStream.readObject()得到java.io.StreamCorruptedException: invalid type code: 4D错误,并通过重写它的write方法将其写入FilterOutputStream内的流:

@Override
public void write(byte[] b, int off, int len) throws IOException {
if(isEncryptionEnabled) {
for(int i=off; i<off+len; i++) {
b[i] = (byte) (b[i] + encryptionKey[i%keySize]);
}
}
super.write(b, off, len);
}

对于FilterInpuStream:

@Override
public int read(byte[] b, int off, int len) throws IOException {
int res = super.read(b, off, len);
if(res > 0 && isEncryptionEnabled) {
for(int i=off; i<off+len; i++) {
b[i] = (byte) (b[i] - encryptionKey[i%keySize]);
}
}
return res;
}
  1. 请不要将其称为"加密"。你的"加密"太琐碎了,一只3岁大的猴子可以解开它。如果我用一点胶水把两个棒棒糖棒打在一起,我认为称之为"桥梁"也不公平。你的密钥交换有多花哨并不重要,如果你在信的开头都是"你好!",我有你的钥匙。查找如何使用,例如AES-256。

  2. 除非发送方在接收方切换的同时在"加密"one_answers"未加密"模式之间切换,否则这显然是行不通的。因此,除非你有一个协议,将所有数据封装在一个数据包中,该数据包以一个指示数据包大小的标识符开始(或者接收器可以通过某种其他机制来确定数据包的结束位置——否则他们只会看到无尽的字节流(,以及它是否加密,否则你不能在单个数据流上"切换"加密。

  3. res不等于len,或者不必等于。read()调用将读取至少1个字节(除非流关闭,在这种情况下,它不读取任何字节,并返回-1(,并且永远不会读取超过len个字节,但它可能会读取介于两者之间的某个字节。

  4. 关键,除非i同步,否则您的加密方案会失败,但不会同步,因为两者之间绝对没有关系。发送器可以发送4096字节的一个块,接收器可以在18个单独的较小步骤中接收它。由于i每次都是0,因此您在encryptionKey中查找错误的字节。

关于代码不起作用的原因,有无数种解释。可能是因为它有多个问题。#4本身就已经是一个亮点了。

最新更新