using System;
using System.Security.Cryptography;
using MinecraftClient.Protocol.Message;
namespace MinecraftClient.Protocol.Keys
{
public class PrivateKey
{
public byte[] Key { get; set; }
private readonly RSA rsa;
private byte[]? precedingSignature = null;
public PrivateKey(string pemKey)
{
Key = KeyUtils.DecodePemKey(pemKey, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----");
rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(Key, out _);
}
public byte[] SignData(byte[] data)
{
return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
///
/// Sign message - 1.19
///
/// Message content
/// Sender uuid
/// Timestamp
/// Salt
/// Signature data
public byte[] SignMessage(string message, Guid uuid, DateTimeOffset timestamp, ref byte[] salt)
{
string messageJson = "{\"text\":\"" + KeyUtils.EscapeString(message) + "\"}";
byte[] data = KeyUtils.GetSignatureData(messageJson, uuid, timestamp, ref salt);
return SignData(data);
}
///
/// Sign message - 1.19.1 and above
///
/// Message content
/// Sender uuid
/// Timestamp
/// Salt
/// LastSeenMessageList
/// Signature data
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);
precedingSignature = msgSign;
return msgSign;
}
}
}