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:
Simplxs
2023-09-17 05:38:39 +08:00
committed by GitHub
Unverified
parent b8f7aea168
commit fb0c2dbc84
9 changed files with 118 additions and 30 deletions
@@ -23,6 +23,9 @@ public class GameSession implements GameSessionManager.KcpChannel {
@Getter @Setter private Account account;
@Getter private Player player;
@Getter private long encryptSeed = Crypto.ENCRYPT_SEED;
private byte[] encryptKey = Crypto.ENCRYPT_KEY;
@Setter private boolean useSecretKey;
@Getter @Setter private SessionState state;
@@ -34,6 +37,11 @@ public class GameSession implements GameSessionManager.KcpChannel {
this.server = server;
this.state = SessionState.WAITING_FOR_TOKEN;
this.lastPingTime = System.currentTimeMillis();
if (GAME_INFO.useUniquePacketKey) {
this.encryptKey = new byte[4096];
this.encryptSeed = Crypto.generateEncryptKeyAndSeed(this.encryptKey);
}
}
public GameServer getServer() {
@@ -133,7 +141,12 @@ public class GameSession implements GameSessionManager.KcpChannel {
event.call();
if (!event.isCanceled()) { // If event is not cancelled, continue.
try {
tunnel.writeData(event.getPacket().build());
packet = event.getPacket();
var bytes = packet.build();
if (packet.shouldEncrypt) {
Crypto.xor(bytes, packet.useDispatchKey() ? Crypto.DISPATCH_KEY : this.encryptKey);
}
tunnel.writeData(bytes);
} catch (Exception ignored) {
Grasscutter.getLogger().debug("Unable to send packet to client.");
}
@@ -149,7 +162,7 @@ public class GameSession implements GameSessionManager.KcpChannel {
@Override
public void handleReceive(byte[] bytes) {
// Decrypt and turn back into a packet
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
Crypto.xor(bytes, useSecretKey() ? this.encryptKey : Crypto.DISPATCH_KEY);
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
// Log
@@ -111,32 +111,33 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Only >= 2.7.50 has this
if (req.getKeyId() > 0) {
var encryptSeed = session.getEncryptSeed();
try {
var cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, Crypto.CUR_SIGNING_KEY);
var client_seed_encrypted = Utils.base64Decode(req.getClientRandKey());
var client_seed = ByteBuffer.wrap(cipher.doFinal(client_seed_encrypted)).getLong();
var clientSeedEncrypted = Utils.base64Decode(req.getClientRandKey());
var clientSeed = ByteBuffer.wrap(cipher.doFinal(clientSeedEncrypted)).getLong();
var seed_bytes =
ByteBuffer.wrap(new byte[8]).putLong(Crypto.ENCRYPT_SEED ^ client_seed).array();
var seedBytes =
ByteBuffer.wrap(new byte[8]).putLong(encryptSeed ^ clientSeed).array();
cipher.init(Cipher.ENCRYPT_MODE, Crypto.EncryptionKeys.get(req.getKeyId()));
var seed_encrypted = cipher.doFinal(seed_bytes);
var seedEncrypted = cipher.doFinal(seedBytes);
var privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(Crypto.CUR_SIGNING_KEY);
privateSignature.update(seed_bytes);
privateSignature.update(seedBytes);
session.send(
new PacketGetPlayerTokenRsp(
session,
Utils.base64Encode(seed_encrypted),
Utils.base64Encode(seedEncrypted),
Utils.base64Encode(privateSignature.sign())));
} catch (Exception ignored) {
// Only UA Patch users will have exception
var clientBytes = Utils.base64Decode(req.getClientRandKey());
var seed = ByteHelper.longToBytes(Crypto.ENCRYPT_SEED);
var seed = ByteHelper.longToBytes(encryptSeed);
Crypto.xor(clientBytes, seed);
var base64str = Utils.base64Encode(clientBytes);
@@ -20,7 +20,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
.setAccountType(1)
.setIsProficientPlayer(
session.getPlayer().getAvatars().getAvatarCount() > 0) // Not sure where this goes
.setSecretKeySeed(Crypto.ENCRYPT_SEED)
.setSecretKeySeed(session.getEncryptSeed())
.setSecurityCmdBuffer(ByteString.copyFrom(Crypto.ENCRYPT_SEED_BUFFER))
.setPlatformType(3)
.setChannelId(1)
@@ -66,7 +66,7 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
.setAccountType(1)
.setIsProficientPlayer(
session.getPlayer().getAvatars().getAvatarCount() > 0) // Not sure where this goes
.setSecretKeySeed(Crypto.ENCRYPT_SEED)
.setSecretKeySeed(session.getEncryptSeed())
.setSecurityCmdBuffer(ByteString.copyFrom(Crypto.ENCRYPT_SEED_BUFFER))
.setPlatformType(3)
.setChannelId(1)