Commit ae8b5e30 authored by Yazawazi's avatar Yazawazi Committed by Luke H-W
Browse files

Full support for both parties

parent 0a557ccf
...@@ -103,26 +103,19 @@ public final class DefaultAuthenticators { ...@@ -103,26 +103,19 @@ public final class DefaultAuthenticators {
String responseMessage = translate("messages.dispatch.account.username_error"); String responseMessage = translate("messages.dispatch.account.username_error");
String loggerMessage = ""; String loggerMessage = "";
String decryptedPassword = ""; String decryptedPassword = "";
try {
byte[] key = FileUtils.readResource("/keys/auth_private-key.der");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey private_key = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
// Get Password Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
if (GAME_OPTIONS.uaPatchCompatible) {
// Make sure your patch can send passwords in plain text
decryptedPassword = request.getPasswordRequest().password;
} else {
try {
byte[] key = FileUtils.readResource("/keys/auth_private-key.der");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey private_key = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, private_key); cipher.init(Cipher.DECRYPT_MODE, private_key);
decryptedPassword = new String(cipher.doFinal(Utils.base64Decode(request.getPasswordRequest().password)), StandardCharsets.UTF_8); decryptedPassword = new String(cipher.doFinal(Utils.base64Decode(request.getPasswordRequest().password)), StandardCharsets.UTF_8);
} catch (Exception ignored) { } catch (Exception ignored) {
ignored.printStackTrace(); decryptedPassword = request.getPasswordRequest().password;
}
} }
if (decryptedPassword == null) { if (decryptedPassword == null) {
......
...@@ -11,6 +11,7 @@ import emu.grasscutter.server.event.dispatch.QueryCurrentRegionEvent; ...@@ -11,6 +11,7 @@ import emu.grasscutter.server.event.dispatch.QueryCurrentRegionEvent;
import emu.grasscutter.server.http.Router; import emu.grasscutter.server.http.Router;
import emu.grasscutter.server.http.objects.QueryCurRegionRspJson; import emu.grasscutter.server.http.objects.QueryCurRegionRspJson;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import express.Express; import express.Express;
import express.http.Request; import express.http.Request;
...@@ -19,6 +20,11 @@ import io.javalin.Javalin; ...@@ -19,6 +20,11 @@ import io.javalin.Javalin;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.security.Signature; import java.security.Signature;
...@@ -139,9 +145,8 @@ public final class RegionHandler implements Router { ...@@ -139,9 +145,8 @@ public final class RegionHandler implements Router {
try { try {
QueryCurrentRegionEvent event = new QueryCurrentRegionEvent(regionData); event.call(); QueryCurrentRegionEvent event = new QueryCurrentRegionEvent(regionData); event.call();
if (GAME_OPTIONS.uaPatchCompatible) { if (request.query("dispatchSeed") == null) {
// More love for UA Patch players // More love for UA Patch players
var rsp = new QueryCurRegionRspJson(); var rsp = new QueryCurRegionRspJson();
rsp.content = event.getRegionInfo(); rsp.content = event.getRegionInfo();
......
...@@ -101,9 +101,29 @@ public class HandlerGetPlayerTokenReq extends PacketHandler { ...@@ -101,9 +101,29 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Only >= 2.7.50 has this // Only >= 2.7.50 has this
if (req.getKeyId() > 0) { if (req.getKeyId() > 0) {
if (GAME_OPTIONS.uaPatchCompatible) { try {
// More love for ua patch plz 😭 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, Crypto.CUR_SIGNING_KEY);
var client_seed_encrypted = Utils.base64Decode(req.getClientSeed());
var client_seed = ByteBuffer.wrap(cipher.doFinal(client_seed_encrypted))
.getLong();
byte[] seed_bytes = ByteBuffer.wrap(new byte[8])
.putLong(Crypto.ENCRYPT_SEED ^ client_seed)
.array();
//Kind of a hack, but whatever
cipher.init(Cipher.ENCRYPT_MODE, req.getKeyId() == 3 ? Crypto.CUR_OS_ENCRYPT_KEY : Crypto.CUR_CN_ENCRYPT_KEY);
var seed_encrypted = cipher.doFinal(seed_bytes);
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(Crypto.CUR_SIGNING_KEY);
privateSignature.update(seed_bytes);
session.send(new PacketGetPlayerTokenRsp(session, Utils.base64Encode(seed_encrypted), Utils.base64Encode(privateSignature.sign())));
} catch (Exception ignore) {
// Only UA Patch users will have exception
byte[] clientBytes = Utils.base64Decode(req.getClientSeed()); byte[] clientBytes = Utils.base64Decode(req.getClientSeed());
byte[] seed = ByteHelper.longToBytes(Crypto.ENCRYPT_SEED); byte[] seed = ByteHelper.longToBytes(Crypto.ENCRYPT_SEED);
Crypto.xor(clientBytes, seed); Crypto.xor(clientBytes, seed);
...@@ -111,29 +131,7 @@ public class HandlerGetPlayerTokenReq extends PacketHandler { ...@@ -111,29 +131,7 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
String base64str = Utils.base64Encode(clientBytes); String base64str = Utils.base64Encode(clientBytes);
session.send(new PacketGetPlayerTokenRsp(session, base64str, "bm90aGluZyBoZXJl")); session.send(new PacketGetPlayerTokenRsp(session, base64str, "bm90aGluZyBoZXJl"));
return;
} }
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, Crypto.CUR_SIGNING_KEY);
var client_seed_encrypted = Utils.base64Decode(req.getClientSeed());
var client_seed = ByteBuffer.wrap(cipher.doFinal(client_seed_encrypted))
.getLong();
byte[] seed_bytes = ByteBuffer.wrap(new byte[8])
.putLong(Crypto.ENCRYPT_SEED ^ client_seed)
.array();
//Kind of a hack, but whatever
cipher.init(Cipher.ENCRYPT_MODE, req.getKeyId() == 3 ? Crypto.CUR_OS_ENCRYPT_KEY : Crypto.CUR_CN_ENCRYPT_KEY);
var seed_encrypted = cipher.doFinal(seed_bytes);
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(Crypto.CUR_SIGNING_KEY);
privateSignature.update(seed_bytes);
session.send(new PacketGetPlayerTokenRsp(session, Utils.base64Encode(seed_encrypted), Utils.base64Encode(privateSignature.sign())));
} }
else { else {
// Send packet // Send packet
......
...@@ -211,7 +211,6 @@ public class ConfigContainer { ...@@ -211,7 +211,6 @@ public class ConfigContainer {
public int cap = 160; public int cap = 160;
public int rechargeTime = 480; public int rechargeTime = 480;
} }
public boolean uaPatchCompatible = false;
} }
public static class JoinOptions { public static class JoinOptions {
...@@ -271,4 +270,4 @@ public class ConfigContainer { ...@@ -271,4 +270,4 @@ public class ConfigContainer {
public String Ip = "127.0.0.1"; public String Ip = "127.0.0.1";
public int Port = 22102; public int Port = 22102;
} }
} }
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment