• 用加密狗控制软件的授权(C#)


    加密狗授权方式介绍

    每只加密狗都有一个固定的序列号,并且一般是无法修改的。软件运行时读取加密狗的序列号进行判断,序列号通过验证后才能正常使用软件。

    选购一套加密狗开发套件

    我选购了SaftNet的USB软件狗,入手后查阅开发资料(不同品牌的加密狗开发资料一般都不同),整理需要用到的开发资源如下:

    • SoftDogSetup.dll:提供加密狗驱动相关操作的DLL

    需要用到以下方法:

    (1)获取狗驱动程序安装信息接口函数GetDogDriverInfo,定义如下:

    int PASCAL GetDogDriverInfo();

    参数:无

    返回值:

    0 没有安装驱动程序

    1 驱动版本相同(并口和usb)

    2 USB驱动版本相同

    3 并口驱动版本相同

    4 已安装旧版本驱动 (并口和usb)

    5 已安装旧版本USB驱动

    6 已安装旧版本并口驱动

    7 已安装新版本驱动 (并口和usb)

    8 已安装新版本USB驱动

    9 已安装新版本并口驱动

    3008 没有管理员权限

    (2)驱动安装的函数接口InstDriver,定义如下:

    Int PASCAL InstDriver(int iFlag);

    参数:

    iFlag = 1 只安装USB狗驱动

    iFlag = 2 只安装并口狗驱动

    iFlag = 3 安装并口狗驱动和USB狗驱动

    返回值:

    如果运行成功则返回0,否则返回错误值。

    (3)驱动卸载的函数接口UninstallDriver,定义如下:

    int PASCAL UninstallDriver(int iFlag);

    参数:

    iFlag = 1 只卸载USB狗驱动

    iFlag = 2 只卸载并口狗驱动

    iFlag = 3 卸载并口狗驱动和USB狗驱动

    返回值:

    如果运行成功则返回0,否则返回错误值。

    • win32dll.dll:提供加密狗读写操作的DLL

    需要用到以下方法:

    (1)DWORD WINAPI DogRead (DWORD dwBytes,DWORD dwAddr,char *pData);

    函数返回0表示读写成功,其它返回值为错误代码。

    变量说明:

    DWORD dwBytes:每次变换或读写操作的字节数

    DWORD dwAddr:每次读写操作时狗中的首地址

    char * pData :指向变换操作缓冲区的数据指针

    实现加密狗授权(C#)

    定义SoftDog类

    首先定义一个SoftDog的静态类,静态类的主要特点如下:

    • 它们仅包含静态成员。
    • 它们不能被实例化。
    • 它们是密封的,不可被继承。
    • 它们不能包含实例构造函数

    using System;

    using System.Runtime.InteropServices;

    namespace HCommon.License

    {

        [StructLayout(LayoutKind.Sequential)]

        public static class SoftDog

        {

        }

    }

    然后,使用DllImport引入使用到的dll方法,因为参数和返回值都很不友好,所以定义为private,不直接向外部公开。

    /// <summary>

    /// 获取狗驱动程序安装信息接口函数GetDogDriverInfo

    /// </summary>

    [DllImport("SoftDogSetup.dll", CharSet = CharSet.Ansi)]

    private static extern ushort GetDogDriverInfo();

    /// <summary>

    /// 驱动安装的函数接口InstDriver

    /// </summary>

    [DllImport("SoftDogSetup.dll", CharSet = CharSet.Ansi)]

    private static extern ushort InstDriver(ushort flag);

    /// <summary>

    /// 驱动卸载的函数接口UninstallDriver

    /// </summary>

    [DllImport("SoftDogSetup.dll", CharSet = CharSet.Ansi)]

    private static extern ushort UninstallDriver(ushort flag);

    /// <summary>

    /// 读取加密狗单函数接口DogRead

    /// </summary>

    [DllImport("win32dll.dll", CharSet = CharSet.Ansi)]

    private static extern uint DogRead(uint length, uint startIndex, byte[] data);

    然后,定义加密狗驱动相关的public方法

    public static bool DriverInstalled

    {

        get

        {

            ushort code = GetDogDriverInfo();

            if (code == 3008) throw new HCommon.HException("{0}:没有管理员权限!", 3008);

            if (code == 1 || code == 2 || code == 7 || code == 8) return true;

            return false;

        }

    }

    public static void InstallDriver()

    {

        ushort code = GetDogDriverInfo();

        if (code == 3008) throw new HCommon.HException("{0}:没有管理员权限!", 3008);

        if (code == 1 || code == 2 || code == 7 || code == 8) return;

        if (code == 4 || code == 5)

            UninstallDriver();

        code = InstDriver(1);

        if (code != 0) throw new HCommon.HException("{0}:安装驱动失败!", code);

    }

    public static void UninstallDriver()

    {

        ushort code = UninstallDriver(1);

        if (code != 0) throw new HCommon.HException("{0}:卸载驱动失败!", code);

    }

    最后,定义读取加密狗序列号的public方法

    public static string SerialNumber

    {

        get

        {

            uint code = 0;

            byte[] data = new byte[100];

            code = DogRead(0, 0, data);

            if (code != 0)

            {

                throw new HCommon.HException("{0}:读取序列号失败!", code);

            }

            uint sn = BitConverter.ToUInt32(data, 0);

            return sn.ToString();

        }

    }

    使用SoftDog类

    使用SoftDog的客户程序代码片段:

    //软件启动时先判断是否安装加密狗驱动

    if (!SoftDog.DriverInstalled)

    {

        SoftDog.InstallDriver();

        MessageBox.Show("已安装加密狗驱动,请插入加密狗。");

    }

    //定义序列号属性

    private static readonly string g_Key = "12345678";

    private string SerialNumber

    {

        get

        {

            try

            {

                string sn = SoftDog.SerialNumber;

                if (string.IsNullOrEmpty(sn)) return string.Empty;

                return sn;

            }

            catch (Exception ex)

            {

                HCommon.ApplicationLog.LogException(ex);

            }

            return string.Empty;

        }

    }

    //序列号判断的方法

    private void CheckLicense()

    {

        if (SerialNumber != g_Key)

        {

            MessageBox.Show("对不起,计算机必须插入正确的加密狗,软件才能授权使用,请按确定退出系统。");

            System.Windows.Forms.Application.Exit();

        }

    }

    另外,软件运行时也应该定期地检查序列号,当发现加密狗已被拔出时终止软件的使用。需要定义一个Timer,每隔2分钟调用一次CheckLicense方法即可。

    几种常用授权方式总结

    • 软件序列号授权:支持单机,序列号容易泄漏。
    • 软件序列号网络注册激活:授权控制最理想,但不支持单机。
    • 加密狗授权:支持单机,效果比软件序列号授权好,但占用一个硬件端口。
  • 相关阅读:
    【BZOJ】1710: [Usaco2007 Open]Cheappal 廉价回文
    【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站
    【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑
    【Atcoder】CODE FESTIVAL 2017 qual A D
    【BZOJ】3038: 上帝造题的七分钟2 && 3211: 花神游历各国
    【BZOJ】1707: [Usaco2007 Nov]tanning分配防晒霜
    【BZOJ】1754: [Usaco2005 qua]Bull Math
    【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
    【BZOJ】1828: [Usaco2010 Mar]balloc 农场分配(经典贪心)
    【BZOJ】1709: [Usaco2007 Oct]Super Paintball超级弹珠
  • 原文地址:https://www.cnblogs.com/hbliu_ren/p/4008323.html
Copyright © 2020-2023  润新知