Skip to content

Commit

Permalink
rsa key create, sha pass encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
shnok committed Jun 28, 2024
1 parent d94c6ac commit cf85769
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 96 deletions.
1 change: 0 additions & 1 deletion l2-unity/Assets/Scripts/Game/Manager/GameManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ private void LoadTables() {
}

public void LogIn() {
LoginClient.Instance.Connect(StringUtils.GenerateRandomString());
}

public void LogOut() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,20 @@ public class AsynchronousClient {
private BlowfishEngine _blowfish;
private Socket _socket;
private string _ipAddress;
private string _username;
private int _port;
private bool _connected;
private ClientPacketHandler _clientPacketHandler;
private ServerPacketHandler _serverPacketHandler;
private DefaultClient _client;
private bool _initPacket = true;

private byte[] _blowfishKey;
public byte[] BlowfishKey { get { return _blowfishKey; } set { _blowfishKey = value; } }
private RSACrypt _rsa;
public RSACrypt RSACrypt { get { return _rsa; } }

private byte[] _blowfishKey;
public byte[] BlowfishKey { get { return _blowfishKey; } set { SetBlowFishKey(value); } }
public string Account { get { return _client.Account; } }
public string Password { get { return _client.Password; } }
public int Ping { get; set; }

public AsynchronousClient(string ip, int port, DefaultClient client, ClientPacketHandler clientPacketHandler, ServerPacketHandler serverPacketHandler) {
Expand All @@ -57,7 +60,14 @@ public AsynchronousClient(string ip, int port, DefaultClient client, ClientPacke
public void SetBlowFishKey(byte[] blowfishKey) {
_blowfishKey = blowfishKey;
_blowfish = new BlowfishEngine();
_blowfish.init(false, AsynchronousClient.STATIC_BLOWFISH_KEY);
_blowfish.init(false, blowfishKey);

Debug.Log("Blowfish key set.");
}

public void SetRSAKey(byte[] rsaKey) {
_rsa = new RSACrypt(rsaKey, true);
Debug.Log("RSA Key set.");
}

public bool Connect() {
Expand Down
86 changes: 43 additions & 43 deletions l2-unity/Assets/Scripts/Networking/ClientLibrary/Crypto/NewCrypt.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
namespace L2_login
{
class NewCrypt
{
public static bool verifyChecksum(byte[] raw)
{
class NewCrypt {
public static bool verifyChecksum(byte[] raw) {
return verifyChecksum(raw, 0, raw.Length);
}

public static bool verifyChecksum(byte[] raw, int offset, int size)
{
public static bool verifyChecksum(byte[] raw, int offset, int size) {
// check if size is multiple of 4 and if there is more then only the checksum
if ((size & 3) != 0 || size <= 4)
{
if ((size & 3) != 0 || size <= 4) {
return false;
}

Expand All @@ -20,8 +16,7 @@ public static bool verifyChecksum(byte[] raw, int offset, int size)
ulong check = ulong.MaxValue;
int i;

for (i = offset; i < count; i += 4)
{
for (i = offset; i < count; i += 4) {
check = (ulong)raw[i] & 0xff;
check |= (ulong)raw[i + 1] << 8 & 0xff00;
check |= (ulong)raw[i + 2] << 0x10 & 0xff0000;
Expand All @@ -38,20 +33,17 @@ public static bool verifyChecksum(byte[] raw, int offset, int size)
return check == chksum;
}

public static void appendChecksum(byte[] raw)
{
public static void appendChecksum(byte[] raw) {
appendChecksum(raw, 0, raw.Length);
}

public static void appendChecksum(byte[] raw, int offset, int size)
{
public static void appendChecksum(byte[] raw, int offset, int size) {
ulong chksum = 0;
int count = size - 4;
ulong ecx;
int i;

for (i = offset; i < count; i += 4)
{
for (i = offset; i < count; i += 4) {
ecx = (ulong)raw[i] & 0xff;
ecx |= (ulong)raw[i + 1] << 8 & 0xff00;
ecx |= (ulong)raw[i + 2] << 0x10 & 0xff0000;
Expand All @@ -78,8 +70,7 @@ public static void appendChecksum(byte[] raw, int offset, int size)
* @param raw The raw bytes to be encrypted
* @param key The 4 bytes (int) XOR key
*/
public static void encXORPass(byte[] raw, int key)
{
public static void encXORPass(byte[] raw, int key) {
encXORPass(raw, 0, raw.Length, key);
}

Expand All @@ -92,15 +83,13 @@ public static void encXORPass(byte[] raw, int key)
* @param size Length of the data to be encrypted
* @param key The 4 bytes (int) XOR key
*/
public static void encXORPass(byte[] raw, int offset, int size, int key)
{
public static void encXORPass(byte[] raw, int offset, int size, int key) {
int stop = size - 8;
int pos = 4 + offset;
int edx;
int ecx = key; // Initial xor key

while (pos < stop)
{
while (pos < stop) {
edx = raw[pos] & 0xFF;
edx |= (raw[pos + 1] & 0xFF) << 8;
edx |= (raw[pos + 2] & 0xFF) << 16;
Expand All @@ -123,35 +112,46 @@ public static void encXORPass(byte[] raw, int offset, int size, int key)
raw[pos++] = (byte)(ecx >> 24 & 0xFF);
}

public static void decXORPass(byte[] raw, int offset, int size, int key)
{
int stop = 4 + offset;
int pos = size - 12;
int edx;
int ecx = key; // Initial xor key

while (stop <= pos)
public static bool decXORPass(byte[] packet) {
int blen = packet.Length;

if (blen < 1 || packet == null)
return false; // TODO: Handle error or throw exception

// Get XOR key
int xorOffset = 8;
uint xorKey = 0;
xorKey |= packet[blen - xorOffset];
xorKey |= (uint)(packet[blen - xorOffset + 1] << 8);
xorKey |= (uint)(packet[blen - xorOffset + 2] << 16);
xorKey |= (uint)(packet[blen - xorOffset + 3] << 24);

// Decrypt XOR encrypted portion
int offset = blen - xorOffset - 4;
uint ecx = xorKey;
uint edx = 0;

while (offset > 2) // Adjust this condition if needed
{
edx = raw[pos] & 0xFF;
edx |= (raw[pos + 1] & 0xFF) << 8;
edx |= (raw[pos + 2] & 0xFF) << 16;
edx |= (raw[pos + 3] & 0xFF) << 24;
edx = (uint)(packet[offset + 0] & 0xFF);
edx |= (uint)(packet[offset + 1] & 0xFF) << 8;
edx |= (uint)(packet[offset + 2] & 0xFF) << 16;
edx |= (uint)(packet[offset + 3] & 0xFF) << 24;

edx ^= ecx;

ecx -= edx;

raw[pos] = (byte)(edx & 0xFF);
raw[pos + 1] = (byte)(edx >> 8 & 0xFF);
raw[pos + 2] = (byte)(edx >> 16 & 0xFF);
raw[pos + 3] = (byte)(edx >> 24 & 0xFF);
pos -= 4;
packet[offset + 0] = (byte)((edx) & 0xFF);
packet[offset + 1] = (byte)((edx >> 8) & 0xFF);
packet[offset + 2] = (byte)((edx >> 16) & 0xFF);
packet[offset + 3] = (byte)((edx >> 24) & 0xFF);

offset -= 4;
}

//raw[pos++] = (byte)(ecx & 0xFF);
//raw[pos++] = (byte)(ecx >> 8 & 0xFF);
//raw[pos++] = (byte)(ecx >> 16 & 0xFF);
//raw[pos++] = (byte)(ecx >> 24 & 0xFF);

return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System;
using System.Security.Cryptography;
using System.Numerics;
using UnityEngine;

public class RSACrypt
{
private RSAParameters _rsaParams;
// hardcoded modulus
private byte[] _modulus = new byte[] { 1, 0, 1 };


public RSACrypt(byte[] exponent, bool needUnscramble) {
if(needUnscramble) {
UnscrambledRSAKey(exponent);
}

InitRSACrypt(exponent);
}

private void InitRSACrypt(byte[] exponent) {
_rsaParams = new RSAParameters {
Modulus = _modulus,
D = exponent
};
}

public void DecryptRSABlock(byte[] encryptedData) {
// Initialize RSA with the parameters
using (RSA rsa = RSA.Create()) {
rsa.ImportParameters(_rsaParams);

// Decrypt the data
byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1);

// Convert decrypted data to string
string decryptedMessage = System.Text.Encoding.UTF8.GetString(decryptedData);
Console.WriteLine("Decrypted Message: " + decryptedMessage);
}
}

public void UnscrambledRSAKey(byte[] rsaKey) {
Debug.Log($"Scrambled RSA: {StringUtils.ByteArrayToString(rsaKey)}");

// step 4 : xor last 0x40 bytes with first 0x40 bytes
for (int i = 0; i < 0x40; i++) {
rsaKey[0x40 + i] = (byte)(rsaKey[0x40 + i] ^ rsaKey[i]);
}
// step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38
for (int i = 0; i < 4; i++) {
rsaKey[0x0d + i] = (byte)(rsaKey[0x0d + i] ^ rsaKey[0x34 + i]);
}
// step 2 : xor first 0x40 bytes with last 0x40 bytes
for (int i = 0; i < 0x40; i++) {
rsaKey[i] = (byte)(rsaKey[i] ^ rsaKey[0x40 + i]);
}
// step 1 : 0x4d-0x50 <-> 0x00-0x04
for (int i = 0; i < 4; i++) {
byte temp = rsaKey[0x00 + i];
rsaKey[0x00 + i] = rsaKey[0x4d + i];
rsaKey[0x4d + i] = temp;
}

Debug.Log($"Unscrambled RSA: {StringUtils.ByteArrayToString(rsaKey)}");
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;

public class SHACrypt
{
public static string ComputeSha256Hash(string rawData) {
// Create a SHA256
using (SHA256 sha256Hash = SHA256.Create()) {
// ComputeHash - returns byte array
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));

// Convert byte array to a string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++) {
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}

public static byte[] ComputeSha256HashToBytes(string rawData) {
// Create a SHA256
using (SHA256 sha256Hash = SHA256.Create()) {
// ComputeHash - returns byte array
return sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override void Parse() {
Identity.SetPosX(ReadF());
Identity.SetPosY(ReadF());
Identity.SetPosZ(ReadF());
Identity.Owned = Identity.Name == GameClient.Instance.Username;
Identity.Owned = Identity.Name == GameClient.Instance.Account;
// Status
Status.Level = ReadI();
Status.Hp = ReadI();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override void Parse() {
Identity.SetPosX(ReadF());
Identity.SetPosY(ReadF());
Identity.SetPosZ(ReadF());
Identity.Owned = Identity.Name == GameClient.Instance.Username;
Identity.Owned = Identity.Name == GameClient.Instance.Account;
// Status
Status.Level = ReadI();
Status.Hp = ReadI();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class InitPacket : ServerPacket {
using UnityEngine;

class InitPacket : ServerPacket {
private int sessionId;
private int rsaKeyLength;
private byte[] publicKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public abstract class ServerPacket : Packet

public ServerPacket(byte[] d) : base(d) {
ReadB();
ReadB();
}

protected byte ReadB() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
Expand Down Expand Up @@ -48,9 +49,28 @@ private void OnPingReceive() {
}

private void OnInitReceive(byte[] data) {
Debug.Log("On init receive");
InitPacket packet = new InitPacket(data);

byte[] rsaKey = packet.PublicKey;
byte[] blowfishKey = packet.BlowfishKey;

_client.SetRSAKey(rsaKey);
_client.SetBlowFishKey(blowfishKey);

string account = _client.Account;
string password = _client.Password;

account = account.ToLower();

byte[] accountBytes = Encoding.UTF8.GetBytes(account);

Debug.Log(accountBytes.Length);
Debug.Log(StringUtils.ByteArrayToString(accountBytes));

byte[] shaPass = SHACrypt.ComputeSha256HashToBytes(password);
Debug.Log(shaPass.Length);
Debug.Log(StringUtils.ByteArrayToString(shaPass));


}
Expand Down
Loading

0 comments on commit cf85769

Please sign in to comment.