Netty客户端未接收到服务器发送的所有数据包

时间:2018-06-24 19:20:12

标签: encryption netty

我有一个Netty服务器和一个Netty客户端,如果我以1秒的延迟发送数据包,则一切正常,但如果我彼此无延迟地发送3-4个数据包,则只有1-2个数据包到达客户端,我没收到,我的客户端数据包解码器:

public class PacketDecoader extends ByteToMessageDecoder {


@Getter
@Setter
private Decryption mode = Decryption.NONE;
@Getter
@Setter
private SecretKey AESKey;

@Override
protected synchronized void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
    PacketSerializer packetSerializer = null;
    System.out.println("Starting decoader for packet");
    if(mode == Decryption.AES) {
        packetSerializer = new 
PacketSerializer(EncryptionUtills.dycryptWithAES(AESKey, msg));
    }
    if(mode == Decryption.NONE) {
        packetSerializer = new PacketSerializer(msg);
    }
    long timestamp = packetSerializer.readVarLong();
    System.out.println("TimeStamp " + timestamp);
    if(System.currentTimeMillis() - timestamp > 2000) {
        System.out.println("Warnig recived packet that was over 2 seconds to late");
        return;
    }
    int id = packetSerializer.readVarInt();
    System.out.println("Packet id " + id);
    Class<? extends Packet> packetclass = NettyClient.getInstance().getPacketRegistry().getClassByID(id);
    if(packetclass == null) {
        System.out.println("No class found for packet with id " + id);
        return;
    }
    Packet packet = packetclass.newInstance();
    packet.Read(packetSerializer);
    if(packetSerializer.getBuf().readableBytes() > 0) {
        System.out.println("Having " + packetSerializer.readableBytes() +" more bytes then red!");
    }
    out.add(packet);    


}

public enum Decryption{
    AES,
    NONE;
}

服务器Encoader:

public class PacketEncoader extends MessageToByteEncoder<Packet>{
@Getter
@Setter
private Encryption mode = Encryption.NONE;
@Getter
@Setter
private SecretKey AESKey;
@Override
protected void encode(ChannelHandlerContext ctx, Packet msg, ByteBuf out) throws Exception {
    int id = NettyServer.getInstance().getPacketRegistry().getIdForPacket(msg);
    if(id == -1) {
        System.out.println(Main.pr + "No id for packet " + msg.getClass().getName());
        return;
    }
    PacketSerializer packetSerializer = new PacketSerializer(out.alloc().buffer());
    packetSerializer.writeVarLong(System.currentTimeMillis());
    packetSerializer.writeVarInt(id);
    msg.Write(packetSerializer);
    if(mode == Encryption.AES) {
        out.writeBytes(EncryptionUtills.encryptWithAES(AESKey, packetSerializer.getBuf()));
    }
    if(mode == Encryption.NONE) {
        out.writeBytes(packetSerializer.getBuf());
    }
    System.out.println("Encoded packet " + msg.getClass().getSimpleName() + " with size " + packetSerializer.writerIndex());
}

public enum Encryption{
AES,
NONE;
}

有没有我忽略的错误?

EncryptionUtills类:

public class EncryptionUtills {



public static ByteBuf decryptWithRSA(ByteBuf encrypted, PrivateKey mykey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, mykey);
    return wrightbytes(encrypted.alloc().buffer(), cipher.doFinal(readbytes(encrypted))); 
}

public static ByteBuf encryptWithRSA(ByteBuf encrypted, PublicKey mykey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, mykey);
    return wrightbytes(encrypted.alloc().buffer(), cipher.doFinal(readbytes(encrypted))); 
}






public static ByteBuf encryptWithAES(SecretKey key, ByteBuf message) throws Exception  {
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return wrightbytes(message.alloc().buffer(), cipher.doFinal(readbytes(message)));
}

public static ByteBuf dycryptWithAES(SecretKey key, ByteBuf message) throws Exception {
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    return wrightbytes(message.alloc().buffer(), cipher.doFinal(readbytes(message)));
}

public static boolean isKeyPairValid(String filename) {
    File file = new File(Main.instance.getDataFolder(), filename + ".key");
    File file2 = new File(Main.instance.getDataFolder(), filename + ".pub");
    return file.exists() && file2.exists();
}

public static KeyPair generateSSLKeyPair(int size, String outfile) throws Exception{
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(size);
    KeyPair kp = kpg.generateKeyPair();
    Key pub = kp.getPublic();
    Key pvt = kp.getPrivate();
    Base64.Encoder encoder = Base64.getEncoder();

    Writer out = new FileWriter(new File(Main.instance.getDataFolder(), outfile + ".key"));
    out.write("-----BEGIN RSA PRIVATE KEY-----\n");
    out.write(encoder.encodeToString(pvt.getEncoded()));
    out.write("\n-----END RSA PRIVATE KEY-----\n");
    out.close();

    out = new FileWriter(new File(Main.instance.getDataFolder(), outfile + ".pub"));
    out.write("-----BEGIN RSA PUBLIC KEY-----\n");
    out.write(encoder.encodeToString(pub.getEncoded()));
    out.write("\n-----END RSA PUBLIC KEY-----\n");
    out.close();
    return kp;
}


public static KeyPair readKeys(File keys) throws Exception {
    Base64.Decoder decoder = Base64.getDecoder();
    Path path = Paths.get(keys + ".key");
    List<String> lines = Files.readAllLines(path);
    byte[] bytes = decoder.decode(lines.get(1));

    /* Generate private key. */
    PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pvt = kf.generatePrivate(ks);

    Path path2 = Paths.get(keys + ".pub");
    List<String> lines2 = Files.readAllLines(path2);
    byte[] bytes2 = decoder.decode(lines2.get(1));

    /* Generate public key. */
    X509EncodedKeySpec ks2 = new X509EncodedKeySpec(bytes2);
    KeyFactory kf2 = KeyFactory.getInstance("RSA");
    PublicKey pub = kf2.generatePublic(ks2);
    return new KeyPair(pub, pvt);
}

public static SecretKey generateAESKey(int size) throws NoSuchAlgorithmException {
     KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(size);
        return kgen.generateKey();
}

private static ByteBuf wrightbytes(ByteBuf wright, byte[] data) {
    int i = 0;
    while (i < data.length) {
        wright.writeByte(data[i]);
        i++;
    }
    return wright;
}
private static byte[] readbytes(ByteBuf buf) {
    int k = buf.readableBytes();
    byte[] data = new byte[k];
    int i = 0;
    while (i < k) {
        data[i] = buf.readByte();
        i++;
    }
    return data;
}

    // The higher the number of iterations the more 
    // expensive computing the hash is for us and
    // also for an attacker.
    private static final int iterations = 20*1000;
    private static final int saltLen = 32;
    private static final int desiredKeyLen = 256;

    /** Computes a salted PBKDF2 hash of given plaintext password
        suitable for storing in a database. 
        Empty passwords are not supported. */
    public static String getSaltedHash(String password) throws Exception {
        byte[] salt = SecureRandom.getInstance("SHA1PRNG").generateSeed(saltLen);
        // store the salt with the password
        return org.apache.commons.codec.binary.Base64.encodeBase64String(salt) + "$" + hash(password, salt);
    }

    /** Checks whether given plaintext password corresponds 
        to a stored salted hash of the password. */
    public static boolean check(String password, String stored) throws Exception{
        String[] saltAndPass = stored.split("\\$");
        if (saltAndPass.length != 2) {
            throw new IllegalStateException(
                "The stored password have the form 'salt$hash'");
        }
        String hashOfInput = hash(password, org.apache.commons.codec.binary.Base64.decodeBase64(saltAndPass[0]));
        return hashOfInput.equals(saltAndPass[1]);
    }

    // using PBKDF2 from Sun, an alternative is https://github.com/wg/scrypt
    // cf. http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html
    private static String hash(String password, byte[] salt) throws Exception {
        if (password == null || password.length() == 0)
            throw new IllegalArgumentException("Empty passwords are not supported.");
        SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecretKey key = f.generateSecret(new PBEKeySpec(
            password.toCharArray(), salt, iterations, desiredKeyLen)
        );
        return org.apache.commons.codec.binary.Base64.encodeBase64String(key.getEncoded());
    }

}

如果有人知道如何解决这个问题,请告诉我

0 个答案:

没有答案