mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-06-02 00:20:43 +08:00
Merge pull request #2341
* enableRandomEncryptSeed * update config version * Merge branch 'Grasscutters:development' into random-seed * make the codes more beautiful * move KahnsSort to algorithms * rename variables * Merge branch 'development' into random-seed
This commit is contained in:
committed by
GitHub
Unverified
parent
b8f7aea168
commit
fb0c2dbc84
@@ -2,6 +2,8 @@ package emu.grasscutter.utils;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.server.http.objects.QueryCurRegionRspJson;
|
||||
import emu.grasscutter.utils.algorithms.MersenneTwister64;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.security.*;
|
||||
@@ -34,9 +36,9 @@ public final class Crypto {
|
||||
|
||||
try {
|
||||
CUR_SIGNING_KEY =
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePrivate(
|
||||
new PKCS8EncodedKeySpec(FileUtils.readResource("/keys/SigningKey.der")));
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePrivate(
|
||||
new PKCS8EncodedKeySpec(FileUtils.readResource("/keys/SigningKey.der")));
|
||||
|
||||
Pattern pattern = Pattern.compile("([0-9]*)_Pub\\.der");
|
||||
for (Path path : FileUtils.getPathsFromResource("/keys/game_keys")) {
|
||||
@@ -46,8 +48,8 @@ public final class Crypto {
|
||||
|
||||
if (m.matches()) {
|
||||
var key =
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePublic(new X509EncodedKeySpec(FileUtils.read(path)));
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePublic(new X509EncodedKeySpec(FileUtils.read(path)));
|
||||
|
||||
EncryptionKeys.put(Integer.valueOf(m.group(1)), key);
|
||||
}
|
||||
@@ -74,8 +76,28 @@ public final class Crypto {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static long generateEncryptKeyAndSeed(byte[] encryptKey) {
|
||||
var encryptSeed = secureRandom.nextLong();
|
||||
var mt = new MersenneTwister64();
|
||||
mt.setSeed(encryptSeed);
|
||||
mt.setSeed(mt.nextLong());
|
||||
mt.nextLong();
|
||||
for (int i = 0; i < 4096 >> 3; i++) {
|
||||
var rand = mt.nextLong();
|
||||
encryptKey[i << 3] = (byte) (rand >> 56);
|
||||
encryptKey[(i << 3) + 1] = (byte) (rand >> 48);
|
||||
encryptKey[(i << 3) + 2] = (byte) (rand >> 40);
|
||||
encryptKey[(i << 3) + 3] = (byte) (rand >> 32);
|
||||
encryptKey[(i << 3) + 4] = (byte) (rand >> 24);
|
||||
encryptKey[(i << 3) + 5] = (byte) (rand >> 16);
|
||||
encryptKey[(i << 3) + 6] = (byte) (rand >> 8);
|
||||
encryptKey[(i << 3) + 7] = (byte) rand;
|
||||
}
|
||||
return encryptSeed;
|
||||
}
|
||||
|
||||
public static QueryCurRegionRspJson encryptAndSignRegionData(byte[] regionInfo, String key_id)
|
||||
throws Exception {
|
||||
throws Exception {
|
||||
if (key_id == null) {
|
||||
throw new Exception("Key ID was not set");
|
||||
}
|
||||
@@ -93,8 +115,8 @@ public final class Crypto {
|
||||
|
||||
for (int i = 0; i < numChunks; i++) {
|
||||
byte[] chunk =
|
||||
Arrays.copyOfRange(
|
||||
regionInfo, i * chunkSize, Math.min((i + 1) * chunkSize, regionInfoLength));
|
||||
Arrays.copyOfRange(
|
||||
regionInfo, i * chunkSize, Math.min((i + 1) * chunkSize, regionInfoLength));
|
||||
byte[] encryptedChunk = cipher.doFinal(chunk);
|
||||
encryptedRegionInfoStream.write(encryptedChunk);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package emu.grasscutter.utils.objects;
|
||||
package emu.grasscutter.utils.algorithms;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package emu.grasscutter.utils.algorithms;
|
||||
|
||||
public final class MersenneTwister64 {
|
||||
// Period parameters
|
||||
private static final int N = 312;
|
||||
private static final int M = 156;
|
||||
private static final long MATRIX_A = 0xB5026F5AA96619E9L; // private static final * constant vector a
|
||||
private static final long UPPER_MASK = 0xFFFFFFFF80000000L; // most significant w-r bits
|
||||
private static final int LOWER_MASK = 0x7FFFFFFF; // least significant r bits
|
||||
|
||||
private final long[] mt = new long[N]; // the array for the state vector
|
||||
private int mti; // mti == N+1 means mt[N] is not initialized
|
||||
|
||||
public synchronized void setSeed(long seed) {
|
||||
mt[0] = seed;
|
||||
for (mti = 1; mti < N; mti++) {
|
||||
mt[mti] = (0x5851F42D4C957F2DL * (mt[mti - 1] ^ (mt[mti - 1] >>> 62)) + mti);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized long nextLong() {
|
||||
int i;
|
||||
long x;
|
||||
final long[] mag01 = {0x0L, MATRIX_A};
|
||||
|
||||
if (mti >= N) { // generate N words at one time
|
||||
if (mti == N + 1) {
|
||||
setSeed(5489L);
|
||||
}
|
||||
|
||||
for (i = 0; i < N - M; i++) {
|
||||
x = (mt[i] & UPPER_MASK) | (mt[i + 1] & LOWER_MASK);
|
||||
mt[i] = mt[i + M] ^ (x >>> 1) ^ mag01[(int) (x & 0x1)];
|
||||
}
|
||||
for (; i < N - 1; i++) {
|
||||
x = (mt[i] & UPPER_MASK) | (mt[i + 1] & LOWER_MASK);
|
||||
mt[i] = mt[i + (M - N)] ^ (x >>> 1) ^ mag01[(int) (x & 0x1)];
|
||||
}
|
||||
x = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||
mt[N - 1] = mt[M - 1] ^ (x >>> 1) ^ mag01[(int) (x & 0x1)];
|
||||
|
||||
mti = 0;
|
||||
}
|
||||
|
||||
x = mt[mti++];
|
||||
x ^= (x >>> 29) & 0x5555555555555555L;
|
||||
x ^= (x << 17) & 0x71D67FFFEDA60000L;
|
||||
x ^= (x << 37) & 0xFFF7EEE000000000L;
|
||||
x ^= (x >>> 43);
|
||||
|
||||
return x;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user