diff --git a/pom.xml b/pom.xml
index a6d53c3..e268f0d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,8 +36,8 @@
org.bouncycastle
- bcprov-jdk15on
- 1.67
+ bcprov-jdk18on
+ 1.86
diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java
index 0a6a3bb..c2a8a3f 100644
--- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java
+++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/PacketTransformation.java
@@ -24,7 +24,7 @@ public class PacketTransformation {
public PacketTransformation(byte[] ivStruct, byte[] fakeMac) {
this.ivStruct = ivStruct;
- this.cipher = new EAXBlockCipher(new AESEngine());
+ this.cipher = new EAXBlockCipher(AESEngine.newInstance());
this.fakeMac = fakeMac;
}
@@ -86,20 +86,18 @@ public class PacketTransformation {
int dataLen = packet.getBody().getSize();
ByteBuffer packetBuffer = packet.writeBody(ByteBuffer.allocate(dataLen).order(ByteOrder.BIG_ENDIAN));
- byte[] result;
- int len;
+ // TS3 derives key and nonce from the packet id, so a resend encrypts under the same pair
+ // again. BouncyCastle refuses that on a cipher that has seen it, hence one per packet.
+ EAXBlockCipher cipher = new EAXBlockCipher(AESEngine.newInstance());
+ cipher.init(true, cipherParameters);
- synchronized (cipher) {
- cipher.init(true, cipherParameters);
+ byte[] result = new byte[cipher.getOutputSize(dataLen)];
+ int len = cipher.processBytes(packetBuffer.array(), 0, dataLen, result, 0);
- result = new byte[cipher.getOutputSize(dataLen)];
- len = cipher.processBytes(packetBuffer.array(), 0, dataLen, result, 0);
-
- try {
- len += cipher.doFinal(result, len);
- } catch (InvalidCipherTextException e) {
- throw new RuntimeException(e);
- }
+ try {
+ len += cipher.doFinal(result, len);
+ } catch (InvalidCipherTextException e) {
+ throw new RuntimeException(e);
}
ByteBuffer outputBuffer = ByteBuffer.allocate(MAC_LEN + headerWithoutMac.length + (len - MAC_LEN));
diff --git a/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java b/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java
index 03461b2..e521337 100644
--- a/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java
+++ b/src/test/java/com/github/manevolent/ts3j/EncryptionTest.java
@@ -53,6 +53,10 @@ public class EncryptionTest extends TestCase {
byte[] packetBytes = transformation.encrypt(packet).array();
transformation.decrypt(header, ByteBuffer.wrap(packetBytes), packet.getBody().getSize());
+
+ // A resend encrypts the same packet again, under the same key and nonce.
+ byte[] resent = transformation.encrypt(packet).array();
+ assertTrue(java.util.Arrays.equals(packetBytes, resent));
}
}