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;
}
///
///
///
private byte[] GetEncryptionKeySeed()
{
var nics = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => i.SupportsMulticast && i.Supports(NetworkInterfaceComponent.IPv4) && i.NetworkInterfaceType == NetworkInterfaceType.Ethernet);
List macAddresses = new List();
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 raw = new List();
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();
}
///
/// Get the 16 bytes encryption key
///
///
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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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 buffer = new Span(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;
}
///
///
///
/// will be converted to UTF8 bytes and then for encryption
/// if set to true, the raw input will be SHA256 firstly and then for encrypting, otherwise, the raw input will be used encrypting directly.
///
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);
}
///
///
///
/// will be converted to UTF8 bytes and then encrypt
/// base64 encoded bytes
public string EncryptStringToBase64(string input)
{
if (string.IsNullOrEmpty(input)) return null;
return Convert.ToBase64String(this.EncryptString(input));
}
///
///
///
/// the raw input for encrypting
/// if set to true, the raw input will be SHA256 firstly and then for encrypting, otherwise, the raw input will be used encrypting directly.
///
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;
}
}
///
///
///
/// the encrypted data
/// return the first 16 bytes from the decrypted data
public byte[] Decrypt(byte[] input)
{
byte[] symmetricKey = this.GetEncryptionKey();
return this.Decrypt(input, symmetricKey);
}
///
/// Decrypt the encrypted data by key.
///
/// the encrypted data
/// the key for decryption
/// the decrypted data
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);
//}
}
}
}
}
}
}