diff --git a/ADP.sln b/ADP.sln index cd8ee83..3a8a9fb 100644 --- a/ADP.sln +++ b/ADP.sln @@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchMovementModule", "Benc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CANModule", "CANModule\CANModule.csproj", "{AF2533DD-599D-49D7-942B-B0C26534D15F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "加密狗", "加密狗\加密狗.csproj", "{A35CA316-7B5B-4183-8636-4ECA532B1489}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -125,6 +127,10 @@ Global {AF2533DD-599D-49D7-942B-B0C26534D15F}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF2533DD-599D-49D7-942B-B0C26534D15F}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF2533DD-599D-49D7-942B-B0C26534D15F}.Release|Any CPU.Build.0 = Release|Any CPU + {A35CA316-7B5B-4183-8636-4ECA532B1489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A35CA316-7B5B-4183-8636-4ECA532B1489}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A35CA316-7B5B-4183-8636-4ECA532B1489}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A35CA316-7B5B-4183-8636-4ECA532B1489}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ADP/ADP.csproj b/ADP/ADP.csproj index 11e86a6..9b029e8 100644 --- a/ADP/ADP.csproj +++ b/ADP/ADP.csproj @@ -33,6 +33,7 @@ + diff --git a/ADP/App.xaml.cs b/ADP/App.xaml.cs index 0e50155..1dee614 100644 --- a/ADP/App.xaml.cs +++ b/ADP/App.xaml.cs @@ -23,6 +23,7 @@ using DeviceCommand.Base; using AutoMapper; using Microsoft.Extensions.Logging.Abstractions; using ADP.Profiles; +using 加密狗; namespace ADP { @@ -75,6 +76,52 @@ namespace ADP RegionManager.SetRegionManager(Application.Current.MainWindow, re); login.Show(); } + protected override void OnStartup(StartupEventArgs e) + { + if (System.Diagnostics.Debugger.IsAttached) + { + base.OnStartup(e); + return; + } + + string strUserSn = "ACA89B2C1194650D4E93D97BE189FFCC"; + string strApiKey = "C6D01BCD442347822876F8232245DE9422643C167B8C61CE4DF6049990E7395588675A8FC6AA4BF7AD353D669C993236BEA83F77551753885A47AF34185CC3A7"; + + Byte[] buffer = new Byte[256]; + buffer = System.Text.Encoding.Default.GetBytes(strUserSn); + uint retcode; + retcode = 加密狗驱动类.验证加密狗SN(buffer); + if (retcode != 0) + { + MessageBox.Show(string.Format("设置UserSN失败 error code: 0x{0:x}", retcode)); + return; + } + + uint count = 0; + retcode = 加密狗API类.VikeyFind(ref count); + if (retcode != 0 || count == 0) + { + MessageBox.Show("未找到加密狗"); + return; + } + + buffer = System.Text.Encoding.Default.GetBytes(strApiKey); + retcode = 加密狗驱动类.验证加密狗APIkey(0, buffer); + if (retcode != 0) + { + MessageBox.Show(string.Format("设置api密钥失败 error code: 0x{0:x}", retcode)); + return; + } + + var remaining = 加密狗驱动类.检查剩余时间(0); + if (remaining <= TimeSpan.Zero) + { + MessageBox.Show("加密狗已到期或未能读取时间,请联系供应商。", "加密狗验证失败", MessageBoxButton.OK, MessageBoxImage.Error); + return; + } + + base.OnStartup(e); + } protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry) { base.RegisterRequiredTypes(containerRegistry); diff --git a/DeviceCommand/Devices/IOBoardGroup.cs b/DeviceCommand/Devices/IOBoardGroup.cs index 220f06e..b9cd41d 100644 --- a/DeviceCommand/Devices/IOBoardGroup.cs +++ b/DeviceCommand/Devices/IOBoardGroup.cs @@ -53,49 +53,49 @@ namespace DeviceCommand.Devices { 功能动作.单相充电, new IoPortInfo(1, 5) }, // Y6 -> 5 { 功能动作.抛负载, new IoPortInfo(1, 0) }, // Y1 -> 0 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 8) } // Y9 -> 8 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 15) } // Y9 -> 8 }}, { 2, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(1, 6) }, // Y7 -> 6 { 功能动作.抛负载, new IoPortInfo(1, 2) }, // Y3 -> 2 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 9) } // Y10 -> 9 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 14) } // Y10 -> 9 }}, { 3, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(1, 7) }, // Y8 -> 7 { 功能动作.抛负载, new IoPortInfo(1, 3) }, // Y4 -> 3 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 10) } // Y11 -> 10 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 13) } // Y11 -> 10 }}, { 4, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(1, 8) }, // Y9 -> 8 { 功能动作.抛负载, new IoPortInfo(1, 4) }, // Y5 -> 4 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 11) } // Y12 -> 11 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 12) } // Y12 -> 11 }}, { 5, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(2, 4) }, // Y5 -> 4 { 功能动作.抛负载, new IoPortInfo(2, 0) }, // Y1 -> 0 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 12) } // Y13 -> 12 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 11) } // Y13 -> 12 }}, { 6, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(2, 5) }, // Y6 -> 5 { 功能动作.抛负载, new IoPortInfo(2, 1) }, // Y2 -> 1 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 13) } // Y14 -> 13 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 10) } // Y14 -> 13 }}, { 7, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(2, 6) }, // Y7 -> 6 { 功能动作.抛负载, new IoPortInfo(2, 2) }, // Y3 -> 2 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 14) } // Y15 -> 14 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 9) } // Y15 -> 14 }}, { 8, new Dictionary<功能动作, IoPortInfo> { { 功能动作.单相充电, new IoPortInfo(2, 7) }, // Y8 -> 7 { 功能动作.抛负载, new IoPortInfo(2, 3) }, // Y4 -> 3 { 功能动作.短路测试, new IoPortInfo(1, 1) }, // Y2 -> 1 - { 功能动作.蜂鸣器报警, new IoPortInfo(2, 15) } // Y16 -> 15 + { 功能动作.蜂鸣器报警, new IoPortInfo(2, 8) } // Y16 -> 15 }} }; diff --git a/加密狗/ViKey.dll b/加密狗/ViKey.dll new file mode 100644 index 0000000..376459f Binary files /dev/null and b/加密狗/ViKey.dll differ diff --git a/加密狗/ViKey7.4.4.dll b/加密狗/ViKey7.4.4.dll new file mode 100644 index 0000000..39d2b36 Binary files /dev/null and b/加密狗/ViKey7.4.4.dll differ diff --git a/加密狗/加密狗.csproj b/加密狗/加密狗.csproj new file mode 100644 index 0000000..d89e0d5 --- /dev/null +++ b/加密狗/加密狗.csproj @@ -0,0 +1,16 @@ + + + + net8.0 + enable + enable + + + + + + Always + + + + diff --git a/加密狗/加密狗API类.cs b/加密狗/加密狗API类.cs new file mode 100644 index 0000000..d2a056f --- /dev/null +++ b/加密狗/加密狗API类.cs @@ -0,0 +1,252 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace 加密狗 +{ + public enum VikeyType + { + ViKeyAPP = 0, //实用型加密狗 + ViKeySTD = 1, //标准型加密狗 + ViKeyNET = 2, //网络型加密狗 + ViKeyPRO = 3, //专业型加密狗 + ViKeyWEB = 4, //身份认证型加密狗 + ViKeyTIME = 5, //时钟型加密狗,内部独立时钟 + ViKeyMultiFunctional = 0x0A, //多功能加密狗 支持软件加密 支持文档加密 + ViKeyMultiFunctionalTime = 0x0B, //多功能时钟加密狗 + ViKeyInvalid //无效类型 + }; + public enum 返回值 : uint + { + /// + /// 成功 + /// + VIKEY_SUCCESS = 0x00000000, + /// + /// 没有找到ViKey加密锁 + /// + VIKEY_ERROR_NO_VIKEY = 0x80000001, + /// + /// 密码错误 + /// + VIKEY_ERROR_INVALID_PASSWORD = 0x80000002, + /// + /// 请先查找加密锁 + /// + VIKEY_ERROR_NEED_FIND = 0x80000003, + /// + /// 无效的句柄 + /// + VIKEY_ERROR_INVALID_INDEX = 0x80000004, + /// + /// 数值错误 + /// + VIKEY_ERROR_INVALID_VALUE = 0x80000005, + /// + /// 秘钥无效 + /// + VIKEY_ERROR_INVALID_KEY = 0x80000006, + /// + /// 读取信息错误 + /// + VIKEY_ERROR_GET_VALUE = 0x80000007, + /// + /// 设置信息错误 + /// + VIKEY_ERROR_SET_VALUE = 0x80000008, + /// + /// 没有机会 + /// + VIKEY_ERROR_NO_CHANCE = 0x80000009, + /// + /// 权限不足 + /// + VIKEY_ERROR_NO_TAUTHORITY = 0x8000000A, + /// + /// 地址或长度错误 + /// + VIKEY_ERROR_INVALID_ADDR_OR_SIZE = 0x8000000B, + /// + /// 获取随机数错误 + /// + VIKEY_ERROR_RANDOM = 0x8000000C, + /// + /// 获取种子错误 + /// + VIKEY_ERROR_SEED = 0x8000000D, + /// + /// 通信错误 + /// + VIKEY_ERROR_CONNECTION = 0x8000000E, + /// + /// 算法或计算错误 + /// + VIKEY_ERROR_CALCULATE = 0x8000000F, + /// + /// 计数器错误 + /// + VIKEY_ERROR_MODULE = 0x80000010, + /// + /// 产生密码错误 + /// + VIKEY_ERROR_GENERATE_NEW_PASSWORD = 0x80000011, + /// + /// 加密数据错误 + /// + VIKEY_ERROR_ENCRYPT_FAILED = 0x80000012, + /// + /// 解密数据错误 + /// + VIKEY_ERROR_DECRYPT_FAILED = 0x80000013, + /// + /// ViKey加密锁已经被锁定 + /// + VIKEY_ERROR_ALREADY_LOCKED = 0x80000014, + /// + /// 无效的命令 + /// + VIKEY_ERROR_UNKNOWN_COMMAND = 0x80000015, + /// + /// 当前ViKey加密锁不支持此功能 + /// + VIKEY_ERROR_NO_SUPPORT = 0x80000016, + /// + /// 发生异常 + /// + VIKEY_ERROR_CATCH = 0x80000017, + /// + /// 未知错误 + /// + VIKEY_ERROR_UNKNOWN_ERROR = 0xFFFFFFFF, + } + + public class 加密狗API类 + { + /// + /// 查找加密锁。使用其他API前必须先调用次函数。 + /// + /// [out] 如果查找到系统中存在加密狗,返回查找到加密狗的个数 + /// 0表示系统中存在ViKey加密狗。 + [DllImport("ViKey.dll")] + public static extern uint VikeyFind(ref uint pdwCount); + /// + /// 获取加密狗的硬件ID,加密狗的硬件ID是加密狗的唯一标识,每个加密狗的硬件ID都不一样。 + /// + /// [in]指定要操作加密狗的序号 + /// [out]返回加密狗的硬件ID + /// + [DllImport("ViKey.dll")] + public static extern uint VikeyGetHID(ushort Index, out uint pdwHID); + + /// + /// 获取加密狗的当前权限 + /// + /// 指定要操作加密狗的序号 + /// 返回加密狗的当前权限 0表示加密狗尚未登录 1表示加密狗是用户权限 2表示加密狗是管理员权限 + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyGetLevel(ushort Index, out byte pLevel); + + /// + /// 以用户权限登录加密狗 + /// + /// + /// + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] + public static extern uint VikeyUserLogin(ushort Index, Byte[] pUserPassword); + /// + /// 以管理员权限登录加密狗 + /// + /// + /// + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] + public static extern uint VikeyAdminLogin(ushort Index, Byte[] pAdminPassword); + /// + /// 注销登录加密狗 注销后的加密狗权限为0 + /// + /// [in]指定要操作加密狗的序号 + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] + public static extern uint VikeyLogoff(ushort Index); + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct SVikeyTime + { + public byte cYear; + public byte cMonth; + public byte cDay; + public byte cHour; + public byte cMinute; + public byte cSecond; + } + /// + /// 获取时钟型加密狗中的内部独立时间 + /// + /// + /// + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyGetTime(ushort Index, out SVikeyTime pTime); + /// + /// 获取时钟型加密狗中的到期时间 + /// + /// + /// + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyGetValidTime(ushort Index, out SVikeyTime pTime); + /// + /// 检测时钟型加密狗的时钟功能是否到期 + /// + /// [in]指定要操作加密狗的序号 + /// [out]返回是否到期结果 1表示没有到期 0表示已经到期 + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyCheckValidTime(ushort Index, out byte pIsValid); + /// + /// 从加密狗中的获取4个双字的随机数数据 + /// + /// 指定要操作加密狗的序号 + /// + /// + /// + /// + /// + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint ViKeyRandom(ushort Index, + out ushort pwRandom1, out ushort pwRandom2, out ushort pwRandom3, out ushort pwRandom4); + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyReadData(ushort Index, ushort Addr, ushort Length, byte[] buffer); + [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)] + public static extern uint VikeyWriteData(ushort Index, ushort Addr, ushort Length, byte[] buffer); + + /// + /// // 7.4.6版本(含)以后的加密狗必须在查找加密狗前调用VikeySetUserSN并输入正确的UserSN后面才能查找到所属用户的加密狗 + // 7.4.6版本以前的加密狗可以忽略此函数 不用调用此函数 + // UserSN在ViKey加密管理工具的->帮助中心页面->复制出来 + /// + /// + /// + [DllImport("ViKey")] + public static extern uint VikeySetUserSN(Byte[] pUserSN); + + /// + /// //设置加密狗ApiKey 硬件版本为7.4.5(含)以后的加密狗必须要调用此接口才能登录 + //ApiKey 是由ViKey加密管理工具的->加密狗管理->密钥设置页面 通过Api密钥种子生成的 + /// + /// + /// + /// + [DllImport("ViKey")] + public static extern uint VikeySetApiKey(ushort Index, Byte[] pApiKey); + + [DllImport("ViKey")] + public static extern uint VikeyUninitialization(); + + } +} diff --git a/加密狗/加密狗驱动类.cs b/加密狗/加密狗驱动类.cs new file mode 100644 index 0000000..33a3e05 --- /dev/null +++ b/加密狗/加密狗驱动类.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace 加密狗 +{ + public class 加密狗驱动类 + { + public static void Uninitialization() + { + 加密狗API类.VikeyUninitialization(); + } + + // 保留原有方法,但添加新方法 + public static int 写入加密狗(ushort Index, string 管理密码, string 校验密码) + { + // 保持不变 + uint 加密狗数量 = 0; + var re = 加密狗API类.VikeyFind(ref 加密狗数量); + if (re != 0) return -1; + 加密狗API类.VikeyAdminLogin(Index, Encoding.Default.GetBytes(管理密码)); + SHA256 sHA256 = SHA256.Create(); + 加密狗API类.VikeyGetHID(Index, out uint pid); + byte[] HID = BitConverter.GetBytes(pid); + var pswd = Encoding.UTF8.GetBytes(校验密码); + byte[] 校验数组 = HID.Concat(pswd).ToArray(); + var 校验值 = sHA256.ComputeHash(校验数组); + 加密狗API类.VikeyWriteData(Index, 0, 32, 校验值); + byte[] randomBytes = new byte[96]; + Random random = new Random(); + random.NextBytes(randomBytes); + 加密狗API类.VikeyWriteData(Index, 32, 96, randomBytes); + return 0; + } + + /// + /// 新方法:仅检查加密狗时间,不验证密码和数据 + /// + public static int 寻找加密狗仅检查时间() + { + uint 加密狗数量 = 0; + var re = 加密狗API类.VikeyFind(ref 加密狗数量); + if (re != 0 || 加密狗数量 == 0) return -1; + + // 直接返回第一个找到的加密狗 + return 0; + } + + /// + /// 原有方法:寻找加密狗并进行完整验证 + /// + public static int 寻找加密狗(string 用户密码,string 校验密码) + { + uint 加密狗数量 = 0; + var re = 加密狗API类.VikeyFind(ref 加密狗数量); + if (re != 0) return -1; + int 找到的加密狗 = -1; + for (ushort i = 0; i < 加密狗数量; i++) + { + re = 加密狗API类.VikeyUserLogin(i, Encoding.Default.GetBytes(用户密码)); + if (检查加密狗数据(i, 校验密码)) return i; + } + return (int)加密狗数量; + } + + public static bool 检查加密狗数据(ushort Index, string 校验密码) + { + // 保持不变 + SHA256 sHA256 = SHA256.Create(); + 加密狗API类.VikeyGetHID(Index, out uint pid); + byte[] HID = BitConverter.GetBytes(pid); + var pswd = Encoding.UTF8.GetBytes(校验密码); + + byte[] 校验数组 = HID.Concat(pswd).ToArray(); + var 校验值 = sHA256.ComputeHash(校验数组); + var buffer = new byte[32]; + 加密狗API类.VikeyReadData(Index, 0, 32, buffer); + + return buffer.SequenceEqual(校验值); + } + + public static TimeSpan 检查剩余时间(int 加密狗) + { + ushort 序号 = (ushort)加密狗; + + try + { + // 读时间前必须先登录(用户权限即可) + uint re = 加密狗API类.VikeyUserLogin(序号, Encoding.Default.GetBytes("11111111")); + if (re != 0) + { + Console.WriteLine($"VikeyUserLogin 失败: 0x{re:X}"); + return TimeSpan.Zero; + } + + re = 加密狗API类.VikeyGetTime(序号, out 加密狗API类.SVikeyTime 现在时间); + if (re != 0) + { + Console.WriteLine($"VikeyGetTime 失败: 0x{re:X}"); + return TimeSpan.Zero; + } + + re = 加密狗API类.VikeyGetValidTime(序号, out 加密狗API类.SVikeyTime 到期时间); + if (re != 0) + { + Console.WriteLine($"VikeyGetValidTime 失败: 0x{re:X}"); + return TimeSpan.Zero; + } + + re = 加密狗API类.VikeyCheckValidTime(序号, out byte isValid); + Console.WriteLine($"VikeyCheckValidTime: ret=0x{re:X}, isValid={isValid}"); + + // cYear 是 byte,ViKey 用距 2000 年的偏移量 + DateTime _现在时间 = new DateTime(现在时间.cYear + 2000, 现在时间.cMonth, 现在时间.cDay, + 现在时间.cHour, 现在时间.cMinute, 现在时间.cSecond); + DateTime _到期时间 = new DateTime(到期时间.cYear + 2000, 到期时间.cMonth, 到期时间.cDay, + 到期时间.cHour, 到期时间.cMinute, 到期时间.cSecond); + + Console.WriteLine($"加密狗当前时间: {_现在时间:yyyy-MM-dd HH:mm:ss}"); + Console.WriteLine($"加密狗到期时间: {_到期时间:yyyy-MM-dd HH:mm:ss}"); + + return _到期时间 - _现在时间; + } + catch (Exception ex) + { + Console.WriteLine($"检查剩余时间异常: {ex.Message}"); + return TimeSpan.Zero; + } + } + + public static uint 验证加密狗SN(Byte[] buffer) + { + return 加密狗API类.VikeySetUserSN(buffer); + } + + public static uint 验证加密狗APIkey(ushort index, Byte[] buffer) + { + return 加密狗API类.VikeySetApiKey(index, buffer); + } + } +} \ No newline at end of file diff --git a/加密狗/本项目的加密狗刷入.cs b/加密狗/本项目的加密狗刷入.cs new file mode 100644 index 0000000..4b305c5 --- /dev/null +++ b/加密狗/本项目的加密狗刷入.cs @@ -0,0 +1,15 @@ +using System; +using 加密狗; + +// ═══════════════════════════════════════════════════════ +// 刷入脚本(独立运行,不属于 ADP 主程序流程) +// 使用前请先用 ViKey 管理工具设置好密码和到期时间 +// ═══════════════════════════════════════════════════════ +public class Program +{ + public static void Main(string[] args) + { + //写入加密狗(需管理员密码) + 加密狗驱动类.写入加密狗(0, "00000000", "ADP项目"); + } +}