123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- using Edge.Core.Parser.BinaryParser.Util;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Logging.Abstractions;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net.NetworkInformation;
- using System.Net.Sockets;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- namespace ShengJuDesFireEv1CpuCardKeyLoader
- {
- public interface IKeyLoader
- {
- DecryptedKeySet Get(EncryptedBase64KeySet input);
- }
- public class DecryptedKeySet
- {
- public byte[] RootKey { get; set; }
- public byte[] 文件1读密钥 { get; set; }
- public byte[] 文件1读写密钥 { get; set; }
- public byte[] 文件2读密钥 { get; set; }
- public byte[] 文件2读写密钥 { get; set; }
- public byte[] 文件3读密钥 { get; set; }
- public byte[] 文件3读写密钥 { get; set; }
- public byte[] 文件4读密钥 { get; set; }
- public byte[] 文件4读写密钥 { get; set; }
- }
- public class InputBase64PlainKeySet
- {
- public string RootKey { get; set; }
- public string 文件1读密钥 { get; set; }
- public string 文件1读写密钥 { get; set; }
- public string 文件2读密钥 { get; set; }
- public string 文件2读写密钥 { get; set; }
- public string 文件3读密钥 { get; set; }
- public string 文件3读写密钥 { get; set; }
- public string 文件4读密钥 { get; set; }
- public string 文件4读写密钥 { get; set; }
- public string Description { get; set; }
- }
- public class EncryptedBase64KeySet
- {
- public string RootKey { get; set; }
- public string 文件1读密钥 { get; set; }
- public string 文件1读写密钥 { get; set; }
- public string 文件2读密钥 { get; set; }
- public string 文件2读写密钥 { get; set; }
- public string 文件3读密钥 { get; set; }
- public string 文件3读写密钥 { get; set; }
- public string 文件4读密钥 { get; set; }
- public string 文件4读写密钥 { get; set; }
- public string Description { get; set; }
- }
- public class LocalNetworkMacBasedEncryptionKeyLoader : IKeyLoader
- {
- private ILogger logger = NullLogger.Instance;
- public LocalNetworkMacBasedEncryptionKeyLoader(ILogger logger)
- {
- this.logger = logger;
- }
- /// <summary>
- /// </summary>
- /// <returns></returns>
- private byte[] GetEncryptionKeySeed()
- {
- var nics = NetworkInterface.GetAllNetworkInterfaces()
- .Where(i => i.SupportsMulticast && i.Supports(NetworkInterfaceComponent.IPv4) && i.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
- List<byte[]> macAddresses = new List<byte[]>();
- string logStr = "";
- for (int i = 0; i < nics.Count(); i++)
- {
- var adapter = nics.ElementAt(i);
- IPInterfaceProperties properties = adapter.GetIPProperties(); // .GetIPInterfaceProperties();
- logStr += $"===========Ethernet {i}: {adapter.Description}==========={Environment.NewLine}";
- logStr += $" Interface type .......................... : {adapter.NetworkInterfaceType}" + Environment.NewLine;
- logStr += $" OperationalStatus ....................... : {adapter.OperationalStatus}" + Environment.NewLine;
- logStr += $" IpAddresses ....................... : " +
- $"{properties.UnicastAddresses.Select(ad => ad.Address).Where(ad => ad.AddressFamily == AddressFamily.InterNetwork).Select(i => i.ToString()).Aggregate("", (acc, n) => acc + ", " + n)}" + Environment.NewLine;
- logStr += $" Physical address ........................ : 0x{adapter.GetPhysicalAddress().GetAddressBytes().ToHexLogString()}" + Environment.NewLine;
- if (adapter.Description.Contains("Virtual", StringComparison.OrdinalIgnoreCase)
- || adapter.Description.Contains("docker", StringComparison.OrdinalIgnoreCase))
- {
- logStr += " --->>Virutal Device<<---" + Environment.NewLine;
- continue;
- }
- macAddresses.Add(adapter.GetPhysicalAddress().GetAddressBytes());
- }
- this.logger.LogInformation($"KeyLoader is preparing for GetEncryptionKey: {Environment.NewLine}{logStr}");
- if (!macAddresses.Any())
- throw new ArgumentException("Failed to generate Encryption Key from local Ethernet NetworkInterface mac addresses");
- List<byte> raw = new List<byte>();
- for (int i = 0; i < macAddresses[0].Length; i++)
- {
- byte accu = 0;
- for (int j = 0; j < macAddresses.Count; j++)
- {
- accu ^= macAddresses[j][i];
- }
- raw.Add(accu);
- }
- //var base64Encoded = Convert.ToBase64String(raw.ToArray());
- this.logger.LogInformation("raw EncryptionKey seed hex: 0x" + raw.ToHexLogString());// + ", base64 encoded: " + base64Encoded);
- return raw.ToArray();
- }
- /// <summary>
- /// Get the 16 bytes encryption key
- /// </summary>
- /// <returns></returns>
- protected virtual byte[] GetEncryptionKey()
- {
- var encryptionKeySeed = this.GetEncryptionKeySeed();
- byte[] symmetricKey = encryptionKeySeed.Concat(Enumerable.Range(0, 16 - encryptionKeySeed.Length).Select(i => (byte)i)).ToArray();
- return symmetricKey;
- }
- public DecryptedKeySet Get(EncryptedBase64KeySet input)
- {
- var output = new DecryptedKeySet();
- if (!string.IsNullOrEmpty(input.RootKey))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.RootKey.Length]);
- if (Convert.TryFromBase64String(input.RootKey, buffer, out int bytesWritten))
- output.RootKey = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped RootKey must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件1读写密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件1读写密钥.Length]);
- if (Convert.TryFromBase64String(input.文件1读写密钥, buffer, out int bytesWritten))
- output.文件1读写密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件1读写密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件1读密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件1读密钥.Length]);
- if (Convert.TryFromBase64String(input.文件1读写密钥, buffer, out int bytesWritten))
- output.文件1读密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件1读密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件2读写密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件2读写密钥.Length]);
- if (Convert.TryFromBase64String(input.文件2读写密钥, buffer, out int bytesWritten))
- output.文件2读写密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件2读写密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件2读密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件2读密钥.Length]);
- if (Convert.TryFromBase64String(input.文件2读密钥, buffer, out int bytesWritten))
- output.文件2读密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件2读密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件3读写密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件3读写密钥.Length]);
- if (Convert.TryFromBase64String(input.文件3读写密钥, buffer, out int bytesWritten))
- output.文件3读写密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件3读写密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件3读密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件3读密钥.Length]);
- if (Convert.TryFromBase64String(input.文件3读密钥, buffer, out int bytesWritten))
- output.文件3读密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件3读密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件4读写密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件4读写密钥.Length]);
- if (Convert.TryFromBase64String(input.文件4读写密钥, buffer, out int bytesWritten))
- output.文件4读写密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件4读写密钥 must be Base64 encodeded format before get decrypting");
- }
- if (!string.IsNullOrEmpty(input.文件4读密钥))
- {
- Span<byte> buffer = new Span<byte>(new byte[input.文件4读密钥.Length]);
- if (Convert.TryFromBase64String(input.文件4读密钥, buffer, out int bytesWritten))
- output.文件4读密钥 = this.Decrypt(buffer.ToArray().Take(bytesWritten).ToArray());
- else
- throw new ArgumentException("the encryped 文件4读密钥 must be Base64 encodeded format before get decrypting");
- }
- return output;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="input">will be converted to UTF8 bytes and then for encryption</param>
- /// <param name="enableHash">if set to true, the raw input will be SHA256 firstly and then for encrypting, otherwise, the raw input will be used encrypting directly.</param>
- /// <returns></returns>
- public byte[] EncryptString(string input, bool enableHash = true)
- {
- if (string.IsNullOrEmpty(input)) throw new ArgumentNullException(nameof(input));
- return this.EncryptBytes(Encoding.UTF8.GetBytes(input), enableHash);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="input">will be converted to UTF8 bytes and then encrypt</param>
- /// <returns>base64 encoded bytes</returns>
- public string EncryptStringToBase64(string input)
- {
- if (string.IsNullOrEmpty(input)) return null;
- return Convert.ToBase64String(this.EncryptString(input));
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="input">the raw input for encrypting</param>
- /// <param name="enableHash">if set to true, the raw input will be SHA256 firstly and then for encrypting, otherwise, the raw input will be used encrypting directly.</param>
- /// <returns></returns>
- public byte[] EncryptBytes(byte[] input, bool enableHash = true)
- {
- byte[] hashedInput = null;
- if (enableHash)
- using (SHA256 hash = SHA256Managed.Create())
- hashedInput = hash.ComputeHash(input);
- else
- hashedInput = input;
- byte[] symmetricKey = this.GetEncryptionKey();
- using (MemoryStream ms = new MemoryStream())
- {
- using (Aes aes = Aes.Create())
- {
- //byte[] symmetricKey = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- // 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
- aes.Key = symmetricKey;
- byte[] iv = aes.IV;
- ms.Write(iv, 0, iv.Length);
- using (CryptoStream cryptoStream = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
- {
- cryptoStream.Write(hashedInput);
- }
- }
- var encryptedBytes = ms.ToArray();//.Take(16).ToArray();
- this.logger.LogInformation($"RawBytes: 0x{input.ToHexLogString()} encrypted to 0x{encryptedBytes.ToHexLogString()}");
- return encryptedBytes;
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="input">the encrypted data</param>
- /// <returns>return the first 16 bytes from the decrypted data</returns>
- public byte[] Decrypt(byte[] input)
- {
- byte[] symmetricKey = this.GetEncryptionKey();
- return this.Decrypt(input, symmetricKey);
- }
- /// <summary>
- /// Decrypt the encrypted data by key.
- /// </summary>
- /// <param name="input">the encrypted data</param>
- /// <param name="key">the key for decryption</param>
- /// <returns>the decrypted data</returns>
- public byte[] Decrypt(byte[] input, byte[] key)
- {
- byte[] symmetricKey = key;
- using (MemoryStream ms = new MemoryStream(input))
- {
- using (Aes aes = Aes.Create())
- {
- byte[] iv = new byte[aes.IV.Length];
- int numBytesToRead = aes.IV.Length;
- int numBytesRead = 0;
- while (numBytesToRead > 0)
- {
- int n = ms.Read(iv, numBytesRead, numBytesToRead);
- if (n == 0) break;
- numBytesRead += n;
- numBytesToRead -= n;
- }
- //byte[] symmetricKey ={
- // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- // 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
- using (CryptoStream cryptoStream = new CryptoStream(ms, aes.CreateDecryptor(symmetricKey, iv), CryptoStreamMode.Read))
- {
- using (MemoryStream outputMs = new MemoryStream())
- {
- cryptoStream.CopyTo(outputMs);
- return outputMs.ToArray();//.Take(16).ToArray();
- }
- //using (var decryptReader = new Text(cryptoStream))
- //{
- // string decryptedMessage = decryptReader.ReadToEnd();
- // Console.WriteLine($"The decrypted original message: {decryptedMessage}, base64 decode to: 0x{Convert.FromBase64String(decryptedMessage).ToHexLogString()}");
- // return Convert.FromBase64String(decryptedMessage);
- //}
- }
- }
- }
- }
- }
- }
|