65.9K
CodeProject 正在变化。 阅读更多。
Home

安全软件分发SDK

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (68投票s)

2002年9月29日

9分钟阅读

viewsIcon

544074

downloadIcon

8037

SSD SDK 通过强大的加密技术为您的共享软件提供安全保障。

目录

描述

SSD SDK 代表“安全软件分发 SDK”,它提供了多种工具和代码,可以阻止大多数对您软件的破解活动。但首先,我们先来看一下最典型的共享软件方案。

X 天/次试用方案

此方案可防止您的软件使用超过预定义的日数(通常为 30 天)或执行次数。这种保护很容易被绕过,因为您的软件必须将剩余的天数或使用次数存储在一个安全的地方,而计算机上没有真正安全的地方。这些值可以被加密或存储在“奇怪”的位置,但这只会延迟不可避免的结果:您的试用期将被重置或延长至无限期。

不完整的软件发布

发布软件的两个版本(完整版和不完整版)非常普遍。完整版是支付了软件费用的所有用户都可以获得的版本。不完整版免费发布给所有人,不用担心破解者,因为他们无法对不完整的软件做什么(好吧,他们可以编写缺失的代码,但这有点傻......)。另一个问题是,恶意注册用户可能会将其“借给”其他用户,从而违反了“一证一用户”的分发概念。

解锁软件

这种软件具有所有完整版的功能,但用户无法使用它们,除非用户支付解锁码,从而释放软件的所有功能。从商业角度来看,这很棒,您只需分发一份软件副本,然后等待解锁请求到达。一封简单的电子邮件和解锁码足以将您的完整软件分发到世界任何地方。但从安全和编程的角度来看,这是一个难题……诸如底层调试器和反汇编器之类的先进工具可用于跟踪和分析您的应用程序,并获取解锁码生成算法,还可以修补您的应用程序代码以避免解锁码保护。

SSD SDK 的开发旨在增强使用第三种技术的应用程序的安全性。它使用强大的加密算法加密您程序的非公开部分,并通过不对称加密防止密钥共享。

工作流程

好了,您手中拥有了几个月编程和调试的成果……您的软件的最终版本已经准备就绪,您想通过万维网将其发布到全世界。但您不想免费赠送,您想发布一个功能受限的版本,并在用户认为(在测试了您的程序后)它很有用时,允许用户扩展这些功能。

是时候仔细思考一下了……当您创建了一个可以自行解锁的软件时,它只允许访问所有时间都存在的代码部分,因此任何人都可以修补您的软件以规避安全问题并像平常一样运行该代码。无论您是使用外部打包器-压缩器-保护器……程序数据和代码在执行时都会在内存中,因此熟练的破解者可以在相对短的时间内将其转储和重建。但是……在这种情况下,我该如何保护我的代码呢?!??!解决方案是加密代码,使其仅对注册用户可用。

加密算法的选择应非常谨慎。这将在“算法和密钥长度”部分讨论。

让我们回到第一步,您手中拥有软件,例如,一个 MPEG 压缩器。该压缩器具有高速压缩和精美的音视频质量,这得益于其多种压缩算法,这些算法基于多种硬件加速技巧,例如 MMX、3dnow! 和 SSE 扩展指令集。

您想发布您的软件,允许用户利用基于 MMX 的算法,但那些想使用 3dnow! 和 SSE 加速压缩的用户应该升级到完整版。您需要做的是发布您的软件,并将扩展算法加密。稍后(在“包含的工具”部分)我将讨论如何创建安全的私钥并使用它来加密您的代码。

一旦用户测试了您的软件并发现他们*需要* 3dnow! 和 SSE 扩展算法,他们就应该获得解密代码的密钥。这可以通过多种方式完成,但最常见的方式是利用公钥密码体系,该体系允许在不使用安全通道传输私钥的情况下,与用户共享私有数据。总之,您的用户联系您,发送一个公钥,该公钥将用于传输解锁密钥。最后,他的“许可证文件”安装在程序目录中,安全代码会验证它并在内存中解密代码。每个用户都有不同的随机公钥/私钥对。这可确保您的许可证不会在不同计算机之间共享。

兼容性

从处理可执行文件并加密代码的那一刻起,您的代码就受到保护。此步骤由一个外部工具完成,该工具打开您的可执行文件并在其节表中查找一个名为 *.secure* 的节;该节包含您的“受保护”代码,并且完全加密。

这意味着您的编译器/链接器应该能够将您想要的任何代码放入一个名称任意的独立节中。在撰写本文时,只找到了一种具有此功能的编译器,那就是 Visual C++。如果您知道其他可以做到这一点的编译器,请通知我。

由于出口限制,某些加密算法在某些国家/地区将无法使用。例如,位于法国的运行 Windows 95、98 或 NT 4 的计算机在某些情况下将无法加密数据。

使用的 API(CryptoAPI 2.0)在 Windows 95 OSR2 及更高版本中可用,因此此代码必须在“任何”Microsoft 32 位操作系统中运行。

软件包内容

  • 命令行工具:*keygen.exe*、*licgen.exe* 和 *protect.exe*。这些工具可帮助您创建密钥、保护您的应用程序并生成许可证。
  • 动态链接库存根:*ssdstub.dll*。需要与您的应用程序一起携带的文件。它在您的软件加载时查找许可证文件并对其进行验证。
  • C++ 代码文件:*ssdhelper.h* 和 *ssdhelper.cpp*。包含“参考”部分中定义的函数的文件。
  • C++ 代码示例:*sample.cpp*。包含一个简单应用程序的代码。您可以在保护“重要”项目之前使用它进行练习。

包含的工具

SSD SDK 包含三个工具。只有在使用带空格的路径时才需要引号(例如 *c:\my docs\target.exe*)。

  • keygen.exe

    创建一个带有随机软件密钥的文件。该文件必须安全地存储在安全的地方(例如 CD-ROM、软盘或加密的硬盘文件)。此文件的命令行参数非常简单。

    keygen.exe "keyfile_path"

    如果未指定文件,则在当前工作目录中创建一个名为 *private.key* 的文件。例如。

    keygen.exe "c:\softwarekey.dat"
  • protect.exe

    使用指定的密钥保护指定的执行文件。

    protect.exe "executable_path" "secretkey_path"

    示例

    protect.exe "c:\coding\project\project.exe" "c:\softwarekey.dat"
  • licgen.exe

    为指定的用户公钥和软件密钥创建相应的用户许可证。

    licgen.exe "secretkey_path" "userkey_path" "output_path"

    示例

    licgen.exe "c:\softwarekey.dat" "c:\userkeys\john.key" 
                                                   "c:\licenses\john.lic"

参考

还有一个最终问题需要回答:我的软件如何创建用户密钥并验证许可证?……别担心,所有这些都包含在一个单独的*.dll*文件中,您只需调用其中一个简单函数即可验证安全上下文。这些函数声明并实现在同一个 SDK 包中的一个文件中,因此您只需将这些文件添加到您的项目中,并在需要时包含头文件。函数规格如下:

  • bool Initialize(const char *lpszApplicationName);

    必须尽快在您的程序执行时间线上调用(从 `main` 函数或 `InitInstance` `CWinApp` 的成员)。此函数会验证许可证(如果存在),并在必要时解密代码。`lpszApplicationName` 应始终与您的应用程序相同,如果两个不同的应用程序(或同一应用程序的不同版本)使用相同的名称,则会发生密钥容器冲突,结果可能不可预测。此函数始终检查 *license.key* 文件,因此不要对用户许可证文件使用其他名称。

  • void ExportKey(const char *lpszFilename);

    创建一个用户公钥文件,该文件应发送给开发人员以获取许可证密钥。您可以通过电子邮件压缩发送此文件,或者在文件开头(或结尾)附加一些与用户相关的信息,但请记住,如果文件头损坏,许可证生成器将无法工作,因此在尝试从给定文件创建任何许可证之前,请剥离其附加信息。`lpszFilename` 指定要创建密钥的文件。

  • bool IsUnlocked();

    如果找到许可证并且软件已用其解密,则返回 `true`。如果不存在许可证文件或其无效,则返回 `false`。

最后,您应该知道如何将受保护的代码存储在具有指定名称的单独节中。在 Visual C++ 编译器/链接器中,这通过 `#pragma code_seg` 语句完成,让我们来看一个简单的例子。

#pragma code_seg(push, r1, ".secure")
void CMyApplication::DoExtendedFunction() {
    // Do something cool ;)
}
#prgama code_seg(pop)

您还可以将所有受保护的代码存储在一个单独的文件中,以避免重复 `#pragma code_seg` 声明。这也可用于非类成员函数。

算法和密钥长度

本文介绍的所有工具和存根代码都是使用 CryptoAPI 2.0 编写的。此 API 提供对称和不对称加密例程,还提供密钥管理、哈希和签名技术。使用的算法和密钥长度如下表所示。

任务 算法 密钥长度
代码加密 RC4 流加密算法 128 位
密钥共享 RSA 公钥交换算法 1024 位

正如优秀的著作“应用密码学手册”中所述,安全的加密系统将其安全性建立在用于加密消息的密钥上,而不是算法的私密性上。换句话说,无论选择的算法是否已发布并经过全球科学界测试,其安全性都取决于加密时可以使用的大量密钥。这确保需要大量的资源(计算机内存和时钟周期)才能找到能够正确解密消息的密钥。

注释

这个小型 SDK 的开发旨在表明,不必花费很多钱就能以良好的保护方案分发我们的软件。它并不完美,但未来将通过其他用户的帮助来弥补细微(或重大)的泄漏和错误。

© . All rights reserved.