Updates
This commit is contained in:
152
SVSim.EmulatedEntrypoint/Security/Encryption.cs
Normal file
152
SVSim.EmulatedEntrypoint/Security/Encryption.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Security;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for encrypting/decrypting requests bodies and responses to/from the game client.
|
||||
/// </summary>
|
||||
public static class Encryption
|
||||
{
|
||||
private const int EncryptionKeySize = 256;
|
||||
private const int EncryptionBlockSize = 128;
|
||||
private const CipherMode EncryptionMode = CipherMode.CBC;
|
||||
private const int UdIdKeySize = 16;
|
||||
private const int KeyStringSize = 32;
|
||||
private const int EncodingValueOffset = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Encrypts an array of bytes using RJ256 with a subset of the user's UdId as the key.
|
||||
/// </summary>
|
||||
/// <param name="sourceData">the data to encrypt</param>
|
||||
/// <param name="udId">the UdId of the user this data is encrypted for</param>
|
||||
/// <returns>the encrypted bytes</returns>
|
||||
public static byte[] Encrypt(byte[] sourceData, string udId)
|
||||
{
|
||||
using (var rj = Aes.Create())
|
||||
{
|
||||
rj.KeySize = EncryptionKeySize;
|
||||
rj.Mode = EncryptionMode;
|
||||
rj.BlockSize = EncryptionBlockSize;
|
||||
string keyString = GenerateKeyString();
|
||||
string udIdKey = udId.Replace("-", string.Empty).Substring(0, UdIdKeySize);
|
||||
byte[] keyStringBytes = Encoding.UTF8.GetBytes(keyString);
|
||||
byte[] rgbIV = Encoding.UTF8.GetBytes(udIdKey);
|
||||
ICryptoTransform transform = rj.CreateEncryptor(keyStringBytes, rgbIV);
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
cs.Write(sourceData);
|
||||
cs.FlushFinalBlock();
|
||||
byte[] encryptedResults = ms.ToArray();
|
||||
byte[] encryptedResultsAndKey = new byte[encryptedResults.Length + keyStringBytes.Length];
|
||||
Array.Copy(encryptedResults, 0, encryptedResultsAndKey, 0, encryptedResults.Length);
|
||||
Array.Copy(keyStringBytes, 0, encryptedResultsAndKey, encryptedResults.Length, keyStringBytes.Length);
|
||||
return encryptedResultsAndKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrypts data that has been encrypted with the given UdId.
|
||||
/// </summary>
|
||||
/// <param name="encryptedData">Previously encrypted data</param>
|
||||
/// <param name="udId">The UdId previously used to encrypt the data</param>
|
||||
/// <returns>the decrypted bytes</returns>
|
||||
public static byte[] Decrypt(byte[] encryptedData, string udId)
|
||||
{
|
||||
using (var rj = Aes.Create())
|
||||
{
|
||||
rj.KeySize = EncryptionKeySize;
|
||||
rj.Mode = EncryptionMode;
|
||||
rj.BlockSize = EncryptionBlockSize;
|
||||
byte[] rgbIv = Encoding.UTF8.GetBytes(udId.Replace("-", string.Empty).Substring(0, UdIdKeySize));
|
||||
byte[] keyBytes = new byte[KeyStringSize];
|
||||
byte[] encryptedValueBytes = new byte[encryptedData.Length - KeyStringSize];
|
||||
Array.Copy(encryptedData, encryptedData.Length - keyBytes.Length, keyBytes, 0, keyBytes.Length);
|
||||
Array.Copy(encryptedData, 0, encryptedValueBytes, 0, encryptedValueBytes.Length);
|
||||
ICryptoTransform transform = rj.CreateDecryptor(keyBytes, rgbIv);
|
||||
using (MemoryStream ms = new MemoryStream(encryptedValueBytes))
|
||||
{
|
||||
using (CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
|
||||
{
|
||||
byte[] decryptedValueBytes = new byte[encryptedValueBytes.Length];
|
||||
cs.Read(decryptedValueBytes, 0, encryptedValueBytes.Length);
|
||||
cs.FlushFinalBlock();
|
||||
return decryptedValueBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string Encode(string sourceData)
|
||||
{
|
||||
int length = sourceData.Length;
|
||||
string encodeBuf = $"{length:x4}";
|
||||
foreach (char value in sourceData)
|
||||
{
|
||||
encodeBuf += $"{GetRandom(),1:x}";
|
||||
encodeBuf += $"{GetRandom(),1:x}";
|
||||
encodeBuf += ((char)(Convert.ToInt32(value) + EncodingValueOffset)).ToString();
|
||||
encodeBuf += $"{GetRandom(),1:x}";
|
||||
}
|
||||
|
||||
encodeBuf += GenerateIvString();
|
||||
return encodeBuf;
|
||||
}
|
||||
|
||||
public static string? Decode(string? encodedData)
|
||||
{
|
||||
if (encodedData == null || encodedData.Length < 4)
|
||||
{
|
||||
return encodedData;
|
||||
}
|
||||
int num = int.Parse(encodedData.Substring(0, 4), NumberStyles.AllowHexSpecifier);
|
||||
string text = "";
|
||||
int num2 = 2;
|
||||
foreach (char value in encodedData.Substring(4, encodedData.Length - 4))
|
||||
{
|
||||
if (num2 % 4 == 0)
|
||||
{
|
||||
text += ((char)(Convert.ToInt32(value) - EncodingValueOffset)).ToString();
|
||||
}
|
||||
num2++;
|
||||
if (text.Length >= num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// TODO Clean this up and de-magic number it
|
||||
private static string GenerateIvString()
|
||||
{
|
||||
string text = "";
|
||||
for (int i = 0; i < KeyStringSize; i++)
|
||||
{
|
||||
text += $"{GetRandom()}";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static string GenerateKeyString()
|
||||
{
|
||||
string text = "";
|
||||
for (int i = 0; i < KeyStringSize; i++)
|
||||
{
|
||||
text += $"{Random.Shared.Next(0, ushort.MaxValue):x}";
|
||||
}
|
||||
return Convert.ToBase64String(Encoding.ASCII.GetBytes(text)).Substring(0, KeyStringSize);
|
||||
}
|
||||
|
||||
private static int GetRandom()
|
||||
{
|
||||
const int MinRandomValue = 1;
|
||||
const int MaxRandomValue = 9;
|
||||
return Random.Shared.Next(MinRandomValue, MaxRandomValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Security.SteamSessionAuthentication;
|
||||
|
||||
public class SteamAuthenticationHandlerOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace SVSim.EmulatedEntrypoint.Security.SteamSessionAuthentication;
|
||||
|
||||
public class SteamSessionAuthenticationHandler : AuthenticationHandler<SteamAuthenticationHandlerOptions>
|
||||
{
|
||||
public SteamSessionAuthenticationHandler(IOptionsMonitor<SteamAuthenticationHandlerOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
|
||||
public SteamSessionAuthenticationHandler(IOptionsMonitor<SteamAuthenticationHandlerOptions> options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder)
|
||||
{
|
||||
}
|
||||
|
||||
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
return AuthenticateResult.Fail("Not implemented");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user