using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using lib; namespace client; public class Message { public uint Id { set; get; } public string Sender { set; get; } public bool IsAck { set; get; } public string Content { set; get; } public byte[] Signature { set; get; } public Message(byte[] bytes) { if (bytes[0] != 0) { Console.WriteLine("Failed parsing message, unsupported version"); } // skip the first byte for simplicity bytes = bytes[1..]; Id = BitConverter.ToUInt32(bytes, 0); Sender = Utils.BytesToNumber(bytes[4..12]); IsAck = bytes[12] != 0; Content = Encoding.UTF8.GetString(bytes[13..bytes.Length]); Signature = []; } public Message(uint Id, string Sender, bool IsAck, string Content) { this.Id = Id; this.Sender = Sender; this.IsAck = IsAck; this.Content = Content; Signature = []; } public void CalculateSignature(RSA key) { Signature = key.SignData(Bytes(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } public bool IsSignatureValid(RSA key) { return key.VerifyData(Bytes(), Signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } public byte[] Bytes() { List msg = []; // 0..4 msg.AddRange(BitConverter.GetBytes(Id)); // 4..12 msg.AddRange(Utils.NumberToBytes(Sender)); // 12 msg.Add((byte)(IsAck ? 1 : 0)); // 13..(len - 32) msg.AddRange(Encoding.UTF8.GetBytes(Content)); return [0, .. msg]; } }