mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Basic support for 1.19.2
This commit is contained in:
parent
af1485c753
commit
c34dd46067
14 changed files with 703 additions and 129 deletions
|
|
@ -1,14 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MinecraftClient.Protocol.Handlers;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
|
||||
namespace MinecraftClient.Protocol.Keys
|
||||
{
|
||||
static class KeyUtils
|
||||
{
|
||||
private static string certificates = "https://api.minecraftservices.com/player/certificates";
|
||||
private static readonly SHA256 sha256Hash = SHA256.Create();
|
||||
|
||||
private static readonly string certificates = "https://api.minecraftservices.com/player/certificates";
|
||||
|
||||
public static PlayerKeyPair? GetKeys(string accessToken)
|
||||
{
|
||||
|
|
@ -67,19 +72,18 @@ namespace MinecraftClient.Protocol.Keys
|
|||
return Convert.FromBase64String(key);
|
||||
}
|
||||
|
||||
public static byte[] GetSignatureData(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt)
|
||||
public static byte[] ComputeHash(byte[] data)
|
||||
{
|
||||
return sha256Hash.ComputeHash(data);
|
||||
}
|
||||
|
||||
public static byte[] GetSignatureData(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt)
|
||||
{
|
||||
List<byte> data = new();
|
||||
|
||||
data.AddRange(salt);
|
||||
|
||||
byte[] UUIDLeastSignificantBits = BitConverter.GetBytes(Convert.ToInt64(uuid[..16], 16));
|
||||
Array.Reverse(UUIDLeastSignificantBits);
|
||||
data.AddRange(UUIDLeastSignificantBits);
|
||||
|
||||
byte[] UUIDMostSignificantBits = BitConverter.GetBytes(Convert.ToInt64(uuid.Substring(16, 16), 16));
|
||||
Array.Reverse(UUIDMostSignificantBits);
|
||||
data.AddRange(UUIDMostSignificantBits);
|
||||
data.AddRange(uuid.ToBigEndianBytes());
|
||||
|
||||
byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds());
|
||||
Array.Reverse(timestampByte);
|
||||
|
|
@ -90,6 +94,39 @@ namespace MinecraftClient.Protocol.Keys
|
|||
return data.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] GetSignatureData(string message, DateTimeOffset timestamp, ref byte[] salt, LastSeenMessageList lastSeenMessages)
|
||||
{
|
||||
List<byte> data = new();
|
||||
|
||||
data.AddRange(salt);
|
||||
|
||||
byte[] timestampByte = BitConverter.GetBytes(timestamp.ToUnixTimeSeconds());
|
||||
Array.Reverse(timestampByte);
|
||||
data.AddRange(timestampByte);
|
||||
|
||||
data.AddRange(Encoding.UTF8.GetBytes(message));
|
||||
|
||||
data.Add(70);
|
||||
|
||||
lastSeenMessages.WriteForSign(data);
|
||||
|
||||
return data.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] GetSignatureData(byte[]? precedingSignature, Guid sender, byte[] bodySign)
|
||||
{
|
||||
List<byte> data = new();
|
||||
|
||||
if (precedingSignature != null)
|
||||
data.AddRange(precedingSignature);
|
||||
|
||||
data.AddRange(sender.ToBigEndianBytes());
|
||||
|
||||
data.AddRange(bodySign);
|
||||
|
||||
return data.ToArray();
|
||||
}
|
||||
|
||||
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
|
||||
public static string EscapeString(string src)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
|
||||
namespace MinecraftClient.Protocol.Keys
|
||||
{
|
||||
|
|
@ -13,6 +14,8 @@ namespace MinecraftClient.Protocol.Keys
|
|||
|
||||
private readonly RSA rsa;
|
||||
|
||||
private byte[]? precedingSignature = null;
|
||||
|
||||
public PrivateKey(string pemKey)
|
||||
{
|
||||
this.Key = KeyUtils.DecodePemKey(pemKey, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----");
|
||||
|
|
@ -26,7 +29,15 @@ namespace MinecraftClient.Protocol.Keys
|
|||
return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
|
||||
public byte[] SignMessage(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt)
|
||||
/// <summary>
|
||||
/// Sign message - 1.19
|
||||
/// </summary>
|
||||
/// <param name="message">Message content</param>
|
||||
/// <param name="uuid">Sender uuid</param>
|
||||
/// <param name="timestamp">Timestamp</param>
|
||||
/// <param name="salt">Salt</param>
|
||||
/// <returns>Signature data</returns>
|
||||
public byte[] SignMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt)
|
||||
{
|
||||
string messageJson = "{\"text\":\"" + KeyUtils.EscapeString(message) + "\"}";
|
||||
|
||||
|
|
@ -35,5 +46,27 @@ namespace MinecraftClient.Protocol.Keys
|
|||
return SignData(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sign message - 1.19.1 and above
|
||||
/// </summary>
|
||||
/// <param name="message">Message content</param>
|
||||
/// <param name="uuid">Sender uuid</param>
|
||||
/// <param name="timestamp">Timestamp</param>
|
||||
/// <param name="salt">Salt</param>
|
||||
/// <param name="lastSeenMessages">LastSeenMessageList</param>
|
||||
/// <returns>Signature data</returns>
|
||||
public byte[] SignMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, LastSeenMessageList lastSeenMessages)
|
||||
{
|
||||
byte[] bodySignData = KeyUtils.GetSignatureData(message, timestamp, ref salt, lastSeenMessages);
|
||||
byte[] bodyDigest = KeyUtils.ComputeHash(bodySignData);
|
||||
|
||||
byte[] msgSignData = KeyUtils.GetSignatureData(precedingSignature, uuid, bodyDigest);
|
||||
byte[] msgSign = SignData(msgSignData);
|
||||
|
||||
this.precedingSignature = msgSign;
|
||||
|
||||
return msgSign;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
|
||||
namespace MinecraftClient.Protocol.Keys
|
||||
{
|
||||
|
|
@ -44,12 +45,53 @@ namespace MinecraftClient.Protocol.Keys
|
|||
return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
|
||||
public bool VerifyMessage(string message, string uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature)
|
||||
/// <summary>
|
||||
/// Verify message - 1.19
|
||||
/// </summary>
|
||||
/// <param name="message">Message content</param>
|
||||
/// <param name="uuid">Sender uuid</param>
|
||||
/// <param name="timestamp">Timestamp</param>
|
||||
/// <param name="salt">Salt</param>
|
||||
/// <param name="signature">Message signature</param>
|
||||
/// <returns>Is this message vaild</returns>
|
||||
public bool VerifyMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature)
|
||||
{
|
||||
byte[] data = KeyUtils.GetSignatureData(message, uuid, timestamp, ref salt);
|
||||
|
||||
return VerifyData(data, signature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify message - 1.19.1 and above
|
||||
/// </summary>
|
||||
/// <param name="message">Message content</param>
|
||||
/// <param name="uuid">Sender uuid</param>
|
||||
/// <param name="timestamp">Timestamp</param>
|
||||
/// <param name="salt">Salt</param>
|
||||
/// <param name="signature">Message signature</param>
|
||||
/// <param name="precedingSignature">Preceding message signature</param>
|
||||
/// <param name="lastSeenMessages">LastSeenMessages</param>
|
||||
/// <returns>Is this message vaild</returns>
|
||||
public bool VerifyMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt, ref byte[] signature, ref byte[]? precedingSignature, LastSeenMessageList lastSeenMessages)
|
||||
{
|
||||
byte[] bodySignData = KeyUtils.GetSignatureData(message, timestamp, ref salt, lastSeenMessages);
|
||||
byte[] bodyDigest = KeyUtils.ComputeHash(bodySignData);
|
||||
|
||||
byte[] msgSignData = KeyUtils.GetSignatureData(precedingSignature, uuid, bodyDigest);
|
||||
|
||||
return VerifyData(msgSignData, signature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify message head - 1.19.1 and above
|
||||
/// </summary>
|
||||
/// <param name="bodyDigest">Message body hash</param>
|
||||
/// <param name="signature">Message signature</param>
|
||||
/// <returns>Is this message header vaild</returns>
|
||||
public bool VerifyHeader(ref byte[] bodyDigest, ref byte[] signature)
|
||||
{
|
||||
return VerifyData(bodyDigest, signature);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue