所以我有一个现有的软件包,它使用Netty通过客户端和服务器之间的加密端口进行通信。当我们将java从1.8.073升级到1.8.161时,我们的问题开始了,我们看到我们的通道加密处理程序失败了。我们确定Oracle移动java的默认RSA加密的变化为2048,而不是像调用默认构造函数时的1024。然而,这个问题是因为公钥大小为1024,其字节大小约为167,我们将使用14字节的随机blob对数据包进行前导,然后将其发送到客户端以加密通道。没有问题这样用73然而在161中编码为字节时的密钥大小是(并且我没有在我面前的笔记)大约269左右... 我们将随机blob读入数据包,通过在第一个字节中编码其长度然后将其数据编码...然后我们将在下一个字节中编码密钥长度,然后编码其数据。问题在于解码。要解码,我们会读取第一个字节以获取随机blob的大小,然后读取下一个字节以获取密钥大小
public static void writeBlob(byte[] blob, ByteBuf buffer)
{
if(debug) {
//System.out.println("Buffer before writing:" + Arrays.toString(readBlob(buffer)));
System.out.println("Blob before writing: Size:"+ blob.length+ " Content:" + Arrays.toString(blob));
}
buffer.writeByte(blob.length);
buffer.writeBytes(blob);
if(debug){
//System.out.println("Buffer after Write: " + Arrays.toString(readBlob(buffer)));
}
}
public static byte[] readBlob(ByteBuf buffer)
{
if(debug) {
//System.out.println("Buffer before writing:" + Arrays.toString(readBlob(buffer)));
System.out.println("Buffer ready to read" );
}
int length = buffer.readUnsignedByte();
byte[] data = new byte[length];
buffer.readBytes(data);
if(debug) {
//System.out.println("Buffer before writing:" + Arrays.toString(readBlob(buffer)));
System.out.println("Data : " + Arrays.toString(data));
}
return data;
}
我注意到的两件事情,即数据包将调整为完整的512字节数据包而不是256字节(显然因为它需要该空间来获取新的扩大密钥)但是当我收到它时数据包被截断为数据的确切大小311字节,这是我编码的。密钥长度是以38字节读取的,而不是用它编码的267字节。
我们的最终结果是升级后初始加密失败,因为关键字节数据被截断。
是否有人能够清楚地知道我在读/写代码中做错了什么,或者这可能是我的网络管道中的更多内容。
附录:这是处理加密开始的子类。
public class PacketOutEncryptStart extends RconPacket
{
public PublicKey key;
public byte[] randomBlob;
public PacketOutEncryptStart() {}
public PacketOutEncryptStart(PublicKey key, byte[] randomBlob, boolean debug)
{
this.key = key;
this.randomBlob = randomBlob;
this.debug=debug;
}
public PacketOutEncryptStart(PublicKey key, byte[] randomBlob)
{
this(key,randomBlob,false);
}
@Override
public void read( ByteBuf packet )
{
randomBlob = readBlob(packet);
key = CryptHelper.decode(readBlob(packet));
}
@Override
public void write( ByteBuf packet )
{
writeBlob(randomBlob, packet);
writeBlob(key.getEncoded(), packet);
}
@Override
public void handlePacket( INetworkHandler handler )
{
((INetworkLoginHandlerClient)handler).handleEncryptStart(this);
}
}