cache: use own Xtea implmentation instead of bouncycastle's
This commit is contained in:
5
cache/pom.xml
vendored
5
cache/pom.xml
vendored
@@ -74,11 +74,6 @@
|
|||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.4</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-ext-jdk14</artifactId>
|
|
||||||
<version>1.54</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import net.runelite.cache.util.BZip2;
|
import net.runelite.cache.util.BZip2;
|
||||||
import net.runelite.cache.io.InputStream;
|
import net.runelite.cache.io.InputStream;
|
||||||
import net.runelite.cache.io.OutputStream;
|
import net.runelite.cache.io.OutputStream;
|
||||||
@@ -432,16 +427,8 @@ public class DataFile implements Closeable
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
Xtea xtea = new Xtea(keys);
|
||||||
{
|
return xtea.decrypt(data, length);
|
||||||
Xtea xtea = new Xtea(keys);
|
|
||||||
return xtea.decrypt(data, length);
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex)
|
|
||||||
{
|
|
||||||
logger.warn("unable to xtea decrypt", ex);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] encrypt(byte[] data, int length, int[] keys)
|
private static byte[] encrypt(byte[] data, int length, int[] keys)
|
||||||
@@ -451,15 +438,7 @@ public class DataFile implements Closeable
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
Xtea xtea = new Xtea(keys);
|
||||||
{
|
return xtea.encrypt(data, length);
|
||||||
Xtea xtea = new Xtea(keys);
|
|
||||||
return xtea.encrypt(data, length);
|
|
||||||
}
|
|
||||||
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex)
|
|
||||||
{
|
|
||||||
logger.warn("unable to xtea encrypt", ex);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,81 +22,67 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.runelite.cache.util;
|
package net.runelite.cache.util;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.security.InvalidKeyException;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.Security;
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
||||||
import org.bouncycastle.util.Arrays;
|
|
||||||
|
|
||||||
public class Xtea
|
public class Xtea
|
||||||
{
|
{
|
||||||
static
|
private static final int GOLDEN_RATIO = 0x9E3779B9;
|
||||||
|
|
||||||
|
private static final int ROUNDS = 32;
|
||||||
|
|
||||||
|
private final int[] key;
|
||||||
|
|
||||||
|
public Xtea(int[] key)
|
||||||
{
|
{
|
||||||
Security.addProvider(new BouncyCastleProvider());
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Cipher cipher;
|
public byte[] encrypt(byte[] data, int len)
|
||||||
private final int[] keys;
|
|
||||||
|
|
||||||
public Xtea(int[] keys) throws NoSuchAlgorithmException, NoSuchPaddingException
|
|
||||||
{
|
{
|
||||||
this.cipher = Cipher.getInstance("XTEA/ECB/NoPadding");
|
ByteBuf buf = Unpooled.wrappedBuffer(data, 0, len);
|
||||||
this.keys = keys;
|
ByteBuf out = Unpooled.buffer(len);
|
||||||
}
|
int numBlocks = len / 8;
|
||||||
|
for (int block = 0; block < numBlocks; ++block)
|
||||||
private static byte[] packKey(int[] key)
|
|
||||||
{
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(4 * key.length);
|
|
||||||
for (int i : key)
|
|
||||||
buffer.putInt(i);
|
|
||||||
return buffer.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] encrypt(byte[] data, int len) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
|
|
||||||
{
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(packKey(keys), cipher.getAlgorithm()));
|
|
||||||
byte[] out = cipher.update(data, 0, len - (len % cipher.getBlockSize()));
|
|
||||||
cipher.doFinal();
|
|
||||||
|
|
||||||
// add remaining data, which is not encrypted
|
|
||||||
if (out.length != len)
|
|
||||||
{
|
{
|
||||||
assert len > out.length;
|
int v0 = buf.readInt();
|
||||||
|
int v1 = buf.readInt();
|
||||||
byte[] padded = Arrays.copyOf(out, len);
|
int sum = 0;
|
||||||
System.arraycopy(data, out.length, padded, out.length, len - out.length);
|
for (int i = 0; i < ROUNDS; ++i)
|
||||||
|
{
|
||||||
out = padded;
|
v0 += (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + key[sum & 3]);
|
||||||
|
sum += GOLDEN_RATIO;
|
||||||
|
v1 += (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + key[(sum >>> 11) & 3]);
|
||||||
|
}
|
||||||
|
out.writeInt(v0);
|
||||||
|
out.writeInt(v1);
|
||||||
}
|
}
|
||||||
|
out.writeBytes(buf);
|
||||||
return out;
|
return out.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] decrypt(byte[] data, int len) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
|
public byte[] decrypt(byte[] data, int len)
|
||||||
{
|
{
|
||||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(packKey(keys), cipher.getAlgorithm()));
|
ByteBuf buf = Unpooled.wrappedBuffer(data, 0, len);
|
||||||
byte[] out = cipher.update(data, 0, len - (len % cipher.getBlockSize()));
|
ByteBuf out = Unpooled.buffer(len);
|
||||||
cipher.doFinal();
|
int numBlocks = len / 8;
|
||||||
|
for (int block = 0; block < numBlocks; ++block)
|
||||||
if (out.length != len)
|
|
||||||
{
|
{
|
||||||
assert len > out.length;
|
int v0 = buf.readInt();
|
||||||
|
int v1 = buf.readInt();
|
||||||
byte[] padded = Arrays.copyOf(out, len);
|
int sum = GOLDEN_RATIO * ROUNDS;
|
||||||
System.arraycopy(data, out.length, padded, out.length, len - out.length);
|
for (int i = 0; i < ROUNDS; ++i)
|
||||||
|
{
|
||||||
out = padded;
|
v1 -= (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + key[(sum >>> 11) & 3]);
|
||||||
|
sum -= GOLDEN_RATIO;
|
||||||
|
v0 -= (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + key[sum & 3]);
|
||||||
|
}
|
||||||
|
out.writeInt(v0);
|
||||||
|
out.writeInt(v1);
|
||||||
}
|
}
|
||||||
|
out.writeBytes(buf);
|
||||||
return out;
|
return out.array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user