1

我正在 VB.NET(用于 Windows)中创建一个应用程序,其中许可证在一年后到期。我可以使用什么日期,用户无法操作来查看一年是否已经过去?

我不希望用户必须在线才能使用该软件,因此在线检查不是一个有效的选项。

谢谢。

4

2 回答 2

2

没有 NIST(网络时间服务器)的基于日期的到期是不稳定的,因为唯一的选择是本地时钟,用户可以摆弄它。每隔一段时间检查一次,比如每两周检查一次,就会出现一个非常大的漏洞:这需要应用程序在某处写下最后一次检查的日期,而在用户的机器上根本不可能保密。

获取大致日期的一种方法是从上次启动日期时间计算它:

Public Class WMI

    Friend Shared Function GetWMISetting(wmiClass As String, value As String) As String
        Dim retVal As String = ""
        Dim query = String.Format("SELECT {0} FROM {1}", value, wmiClass)

        Using searcher As New System.Management.ManagementObjectSearcher(query)
            For Each item As System.Management.ManagementObject In searcher.Get
                For Each p As System.Management.PropertyData In item.Properties
                    If String.Compare(value, p.Name,
                                      StringComparison.InvariantCultureIgnoreCase) = 0 Then
                        If p.Value IsNot Nothing Then
                            retVal = p.Value.ToString
                        End If
                        Exit For
                    End If
                Next
            Next
        End Using
        Return retVal

    End Function

    Friend Shared Function GetMinSystemDateTime() As DateTime

        Dim lastBoot = WMI.GetWMISetting("Win32_OperatingSystem", "LastBootUpTime")
        Dim uptime = WMI.GetWMISetting("Win32_PerfFormattedData_PerfOS_System", 
                   "SystemUpTime")

        Dim ts As New TimeSpan(0, 0, Convert.ToInt32(uptime))
        Dim MinimumDate = ManagementDateTimeConverter.ToDateTime(lastBoot).Add(ts)

        Return MinimumDate  
    End Function
End Class

计算从LastBootUp日期和SystemUpTime值的大致日期。后者可以在TaskManager的Performance选项卡上看到。日期格式比较特殊,所以命名空间提供了一个转换器。System.Management

返回的日期是近似的,因为“UpTime”不包括睡眠时间。否则,它会让您大致了解最短日期。

他们可能会使用虚拟机来欺骗这一点,如果电池没电了,这可能是完全错误的,他们不会让 Windows 设置时间,因此 PC 永久关闭。如果您的许可证包含安装/颁发日期(由您在内政部设置,而不是客户端 PC),您可以测试返回的日期是否小于安装日期并将其视为过期。

然后诀窍就变成了保护这些价值观。颁发许可证时,将用户名、序列号、安装日期和到期日期序列化到 MemoryStream。然后对数据运行 RSA 哈希以创建非对称签名。

创建一个类以将许可证数据保存为 base64 字符串和签名哈希,并将其序列化为文件。在运行时,打开它并使用许可证数据和私钥验证签名。如果验证通过,则“许可证”部分中的数据有效。1

最终,他们真的只需要修补你的代码:

' from:
IsRegistered = ValidateLicense()
' to:
IsRegistered = (True = True)

混淆您的应用程序以减慢它们的速度。

现在,如果你认为这样的事情会阻止你 80% 的可能用户群,那就去做吧。

the user can not manipulate部分是不可行的,但您可以制定一个可以在一定程度上发挥作用的解决方案。你想要阻止的人(破解者 vs 超级用户 vs AOL-LoLs)决定了你需要多广泛或多复杂。

1这样的文件在客户端是只读的。您不能在不使签名无效的情况下对其进行写入。如果不将私钥包含在自杀的应用程序中,您将无法更新/更改它。

于 2013-10-03T19:58:31.107 回答
0

如果您不愿意查看在线时钟/服务/等,则无法这样做,因为用户可以随时更改时间,而您无法阻止。

但是,您可以使用 2 个日期检查篡改。一个用于到期,一个用于检查篡改。每次他们加载您的应用程序时,它应该始终 > 到期日期 - 1 年,并且应该比他们上次启动您的应用程序的时间长。粗略地说,您希望这些加密,因此它们不能篡改这些日期。

这使得它变得比用户的价值更麻烦,他们最终会被锁定,可能需要一年的时间,但它会发生。

想想这个问题,什么会阻止他们删除您的文件/注册表设置并重新开始。如何格式化他们的硬盘驱动器或进行系统还原。也许他们使用虚拟 PC 或某种类型的撤消磁盘。你如何克服这一点?

于 2013-10-03T19:25:45.737 回答