using Luski.net.Enums; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Text.Json; using JacobTechEncryption; namespace Luski.net { public static class ClientEncryption { internal static string? MyPublicKey; internal static readonly UnicodeEncoding Encoder = new(); private static string? myPrivateKey; internal static bool Generating = false; internal static bool Generated = false; private static string? _serverpublickey = null; internal static string? ofkey = null; internal static string? outofkey = null; internal static string pw = ""; public static int NewKeySize = 4096; public static void GenerateKeys() { if (!Generating) { Generating = true; GenerateNewKeys(out MyPublicKey, out myPrivateKey); GenerateNewKeys(out outofkey, out ofkey); Generated = true; } } public static void GenerateNewKeys(out string Public, out string Private) { using RSACryptoServiceProvider r = new(NewKeySize); Private = r.ToXmlString(true); Public = r.ToXmlString(false); return; } public static class File { internal static void SetOfflineKey(string key) { MakeFile("Server.GetKeyFilePath", pw); LuskiDataFile? fileLayout = JsonSerializer.Deserialize(FileString("Server.GetKeyFilePath", pw)); fileLayout.OfflineKey = key; fileLayout.Save("Server.GetKeyFilePath", pw); } public static LuskiDataFile GetFile() { MakeFile("Server.GetKeyFilePath", pw); return JsonSerializer.Deserialize(FileString("Server.GetKeyFilePath", pw))!; } internal static string? GetOfflineKey() { MakeFile("Server.GetKeyFilePath", pw); LuskiDataFile? fileLayout = JsonSerializer.Deserialize(FileString("Server.GetKeyFilePath", pw)); return fileLayout?.OfflineKey; } private static string FileString(string path, string password) { byte[] passwordBytes = Encoding.UTF8.GetBytes(password); byte[] salt = new byte[100]; FileStream fsCrypt = new(path, FileMode.Open); fsCrypt.Read(salt, 0, salt.Length); RijndaelManaged AES = new() { KeySize = 256, BlockSize = 128 }; Rfc2898DeriveBytes key = new(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Padding = PaddingMode.PKCS7; AES.Mode = CipherMode.CFB; CryptoStream cs = new(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read); MemoryStream fsOut = new(); int read; byte[] buffer = new byte[1048576]; try { while ((read = cs.Read(buffer, 0, buffer.Length)) > 0) { fsOut.Write(buffer, 0, read); } } catch (CryptographicException ex_CryptographicException) { Console.WriteLine("CryptographicException error: " + ex_CryptographicException.Message); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } fsOut.Seek(0, SeekOrigin.Begin); using BinaryReader reader = new(fsOut); byte[] by = reader.ReadBytes((int)fsOut.Length); fsOut.Close(); fsCrypt.Close(); return Encoding.UTF8.GetString(by); } public static class Channels { public static string GetKey(long channel) { LuskiDataFile? fileLayout; IEnumerable? lis; try { #pragma warning disable CS8603 // Possible null reference return. if (channel == 0) return myPrivateKey; #pragma warning restore CS8603 // Possible null reference return. MakeFile("Server.GetKeyFilePath", pw); fileLayout = JsonSerializer.Deserialize(FileString("Server.GetKeyFilePath", pw)); lis = fileLayout?.channels?.Where(s => s.id == channel); if (lis?.Count() > 0) { return lis.First().key; } throw new Exception("You dont have a key for that channel"); } finally { fileLayout = null; lis = null; } } internal static string GetKeyBranch(long channel) { LuskiDataFile? fileLayout; IEnumerable? lis; try { #pragma warning disable CS8603 // Possible null reference return. if (channel == 0) return myPrivateKey; #pragma warning restore CS8603 // Possible null reference return. MakeFile("Server.GetKeyFilePathBr(branch.ToString())", pw); fileLayout = JsonSerializer.Deserialize(FileString("", pw)); lis = fileLayout?.channels?.Where(s => s.id == channel); if (lis?.Count() > 0) { return lis.First().key; } throw new Exception("You dont have a key for that channel"); } finally { fileLayout = null; lis = null; } } public static void AddKey(long channel, string key) { MakeFile("Server.GetKeyFilePath", pw); LuskiDataFile? fileLayout = JsonSerializer.Deserialize(FileString("Server.GetKeyFilePath", pw)); fileLayout?.Addchannelkey(channel, key); fileLayout?.Save("Server.GetKeyFilePath", pw); } } private static void MakeFile(string dir, string password) { if (!System.IO.File.Exists(dir)) { LuskiDataFile? l = JsonSerializer.Deserialize("{\"channels\":[]}"); l?.Save(dir, password); } } public class LuskiDataFile { public static LuskiDataFile GetDataFile(string path, string password) { MakeFile(path, password); return JsonSerializer.Deserialize(FileString(path, password)); } internal static LuskiDataFile GetDefualtDataFile() { return GetDataFile("Server.GetKeyFilePath", pw); } public ChannelLayout[]? channels { get; set; } = default!; public string? OfflineKey { get; set; } = default!; public void Save(string file, string password) { byte[] salt = new byte[100]; RandomNumberGenerator? provider = RandomNumberGenerator.Create(); provider.GetBytes(salt); FileStream fsCrypt = new(file, FileMode.Create); byte[] passwordBytes = Encoding.UTF8.GetBytes(password); RijndaelManaged AES = new() { KeySize = 256, BlockSize = 128, Padding = PaddingMode.PKCS7 }; Rfc2898DeriveBytes key = new(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Mode = CipherMode.CFB; fsCrypt.Write(salt, 0, salt.Length); CryptoStream cs = new(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write); string tempp = JsonSerializer.Serialize(this); MemoryStream fsIn = new(Encoding.UTF8.GetBytes(tempp)); byte[] buffer = new byte[1048576]; int read; try { while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) { cs.Write(buffer, 0, read); } fsIn.Close(); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } finally { cs.Close(); fsCrypt.Close(); } } public void Addchannelkey(long chan, string Key) { List? chans = channels?.ToList(); if (chans is null) chans = new(); if (!(chans?.Where(s => s.id == chan).Count() > 0)) { ChannelLayout l = new() { id = chan, key = Key }; chans?.Add(l); channels = chans?.ToArray(); } else { chans.Remove(chans.Where(s => s.id == chan).First()); ChannelLayout l = new() { id = chan, key = Key }; chans?.Add(l); channels = chans?.ToArray(); } } } public class ChannelLayout { public long id { get; set; } = default!; public string key { get; set; } = default!; } } /* public class AES { public static string Encrypt(string path, string Password) { string p = Path.GetTempFileName(); byte[] salt = RandomNumberGenerator.GetBytes(100); byte[] passwordBytes = Encoding.UTF8.GetBytes(Password); Rfc2898DeriveBytes key = new(passwordBytes, salt, 50000); byte[] data = System.IO.File.ReadAllBytes(path); using Aes aesAlg = Aes.Create(); aesAlg.KeySize = 256; aesAlg.BlockSize = 128; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); using FileStream msEncrypt = new(p, FileMode.Open); msEncrypt.Write(salt, 0, salt.Length); using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write); csEncrypt.Write(data, 0, data.Length); csEncrypt.Dispose(); msEncrypt.Dispose(); return p; /* string p = Path.GetTempFileName(); byte[] salt = new byte[100]; RNGCryptoServiceProvider provider = new(); provider.GetBytes(salt); FileStream fsCrypt = new(p, FileMode.Open); byte[] passwordBytes = Encoding.UTF8.GetBytes(Password); Aes AES = Aes.Create(); AES.KeySize = 256; AES.BlockSize = 128; AES.Padding = PaddingMode.PKCS7; Rfc2898DeriveBytes key = new(passwordBytes, salt, 50000); AES.Key = key.GetBytes(AES.KeySize / 8); AES.IV = key.GetBytes(AES.BlockSize / 8); AES.Mode = CipherMode.CFB; fsCrypt.Write(salt, 0, salt.Length); key.Dispose(); CryptoStream cs = new(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write); FileStream fsIn = new(path, FileMode.Open); try { FileInfo FI = new(path); byte[] buffer = new byte[FI.Length]; int read; while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) { cs.Write(buffer, 0, read); } } catch (OutOfMemoryException ex) { throw new Exception("Buffer", ex); } fsIn.Close(); fsIn.Dispose(); cs.Close(); cs.Dispose(); fsCrypt.Close(); fsCrypt.Dispose(); NewPath = p; } public static void Decrypt(byte[] data, string Password, string File) { byte[] salt = new byte[100]; using MemoryStream fsCrypt = new(data); fsCrypt.Read(salt, 0, salt.Length); byte[] passwordBytes = Encoding.UTF8.GetBytes(Password); Rfc2898DeriveBytes key = new(passwordBytes, salt, 50000); byte[] decrypted = new byte[data.Length - salt.Length]; using Aes aesAlg = Aes.Create(); aesAlg.KeySize = 256; aesAlg.BlockSize = 128; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8); ICryptoTransform encryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using CryptoStream csEncrypt = new(fsCrypt, encryptor, CryptoStreamMode.Read); FileStream fsOut = new(File, FileMode.Create); int read; byte[] buffer = new byte[data.Length]; while ((read = csEncrypt.Read(buffer, 0, buffer.Length)) > 0) { fsOut.Write(buffer, 0, read); } csEncrypt.Dispose(); fsCrypt.Dispose(); fsOut.Dispose(); } } */ internal const int PasswordVersion = 0; internal static byte[] LocalPasswordEncrypt(byte[] Password, int PasswordVersion = PasswordVersion) { return PasswordVersion switch { 0 => SHA256.Create().ComputeHash(Password), _ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)), }; } internal static string RemotePasswordEncrypt(byte[] Password, int PasswordVersion = PasswordVersion) { return PasswordVersion switch { 0 => Convert.ToBase64String(Encryption.RSA.Encrypt(LocalPasswordEncrypt(Password, PasswordVersion), MyPublicKey)), _ => throw new ArgumentException("The value provided was not accepted", nameof(PasswordVersion)), }; } /* public static byte[] Hash(byte[] data) { return SHA256.Create().ComputeHash(data); } internal static byte[] Encrypt(string data) { return Encrypt(data, ServerPublicKey); } internal static byte[] Encrypt(byte[] data) { return Encrypt(data, ServerPublicKey); } internal static byte[] Encrypt(string data, string key, bool multithread = false) { return Encrypt(Encoder.GetBytes(data), key, multithread); } internal static byte[] Encrypt(byte[] data, string key, bool multithread = false) { using RSACryptoServiceProvider rsa = new(); rsa.FromXmlString(key); int size = ((rsa.KeySize - 384) / 8) + 7; double x = data.Length / (double)size; int bbb = int.Parse(x.ToString().Split('.')[0]); if (x.ToString().Contains('.')) bbb++; byte[]? datasplitout = Array.Empty(); if (multithread) { byte[][]? decccc = Array.Empty(); Array.Resize(ref decccc, bbb); int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * Server.Percent) * 2.0)); if (num == 0) num = 1; Parallel.For(0, bbb, new ParallelOptions() { MaxDegreeOfParallelism = num }, i => { decccc[i] = rsa.Encrypt(data.Skip(i * size).Take(size).ToArray(), true); }); foreach (byte[] dataa in decccc) { datasplitout = Combine(datasplitout, dataa); } } else { for (int i = 0; i < bbb; i++) { datasplitout = Combine(datasplitout, rsa.Encrypt(data.Skip(i * size).Take(size).ToArray(), false)); } } return datasplitout; } private static byte[] Combine(byte[] first, byte[] second) { byte[]? bytes = new byte[first.Length + second.Length]; Buffer.BlockCopy(first, 0, bytes, 0, first.Length); Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length); return bytes; } internal static byte[] Decrypt(byte[] EncryptedText, bool multithread = false) { return Decrypt(EncryptedText, myPrivateKey, multithread); } internal static byte[] Decrypt(byte[]? EncryptedText, string? key, bool multithread = false) { if (key is null) throw new ArgumentNullException(nameof(key)); if (EncryptedText is null) throw new ArgumentNullException(nameof(EncryptedText)); using RSACryptoServiceProvider rsa = new(); rsa.FromXmlString(key); int size = rsa.KeySize / 8; double x = EncryptedText.Length / (double)size; int bbb = int.Parse(x.ToString().Split('.')[0]); if (x.ToString().Contains('.')) bbb++; byte[]? datasplitout = Array.Empty(); if (multithread) { byte[][]? decccc = Array.Empty(); Array.Resize(ref decccc, bbb); int num = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * Server.Percent) * 2.0)); if (num == 0) num = 1; Parallel.For(0, bbb, new ParallelOptions() { MaxDegreeOfParallelism = num }, i => { decccc[i] = rsa.Decrypt(EncryptedText.Skip(i * size).Take(size).ToArray(), true); }); foreach (byte[] data in decccc) { datasplitout = Combine(datasplitout, data); } } else { for (int i = 0; i < bbb; i++) { datasplitout = Combine(datasplitout, rsa.Decrypt(EncryptedText.Skip(i * size).Take(size).ToArray(), false)); } } return datasplitout; }*/ } }