穷人序列号生成方案,第2部分

时间:2016-02-25 14:28:31

标签: c encryption

这是我上一个问题的延续:

Poor man serial number generation scheme

假设我已生成私钥/公钥对,但我希望在注册的应用程序本身中保存私钥 - 例如,通过生成仅包含数据(公钥和私钥部分)的.c代码。

当然这是一个有风险的解决方案 - 因为如果黑客从应用程序中提取私钥 - 他可以自己创建许可证。

但这是“穷人解决方案”,所以我希望一切都在一个应用程序 - 私钥和公钥 - 所以注册表格也将是序列号生成对话框。

所以我想将私钥放在应用程序中,但要用一些密码保护它,只有我知道。

因此,通过输入序列号 - 在第一遍中我们尝试匹配特定硬件(验证签名),但如果那个不成功,我们尝试检查最终用户是否是“管理员”(或序列号生成人员) )。

什么是最好的双向加密算法,它将使用密码作为输入并且能够容忍暴力攻击?

我猜“管理员密码”应该足够可靠,不容易猜到(没有在任何众所周知的暴力黑客词典中列出)。

将密码存储在注册表中或至少以加密形式存储也是一件好事。密码可能有意义=== sha-1 hash ===> 20个字节哈希 - 将其存储在注册表中(“管理员密码”),然后使用哈希来加密私钥。

与上一个问题相同的问题 - 作为基础,我更喜欢使用普通的C或C ++(而不是C#),最好使用Windows / wincrypt.h或任何现有的普通C源代码(最好不要使用庞大的第3方库)。

2 个答案:

答案 0 :(得分:0)

在这里发表了答案:

Poor man serial number generation scheme

在我自己的原型中,我使用RC4流加密算法进行双向加密。

可靠吗?有人可以破解它吗?!

答案 1 :(得分:0)

注意事项:

  1. 这不是对给定加密算法的直接问题的答案,而是基于您发布的两个问题以及答案和评论的更多关于您的总体目标的答案。
  2. 虽然我一般都会关注软件安全问题,但我是专家,所以请相应地采取我在此处说的任何内容。
  3. 您正在尝试保护自己的软件。也就是说,您正在寻找的是实施许可方案的一种方式。

    您需要[并希望拥有],但未发布的是此功能/设计规范。双向加密只是其中的一部分。

    你不是第一个需要这个的人。已有方案可以做到这一点。我建议使用现有的解决方案。可能有一个公共/免费的开源版本。

    您谈到了电子邮件和注册表单以及剪切和粘贴,但没有详细说明其工作原理。你也没有提到它如何与你的应用程序交互。您是使用网络浏览器注册还是让应用程序出现注册对话框?

    我猜你有一个用户在表单中输入一个电子邮件地址。然后,您的服务器将发回一封包含一些特殊代码的电子邮件[例如,有效期为15分钟的用户必须输入以完成注册以证明电子邮件是有效的,以及系统身份信息。

    您提到剪切和粘贴是限制因素。但是,IMO,并非,因为您可以将密钥放在MIME编码的附件中,并让用户将其保存到文件中。然后,注册表格可以上传此文件。即使是冗长的值(例如,10行72个字符/行)仍然可以放在剪贴板中。

    您收集[希望]有关客户端系统的唯一标识信息。在大多数奔腾III级处理器上,CPU序列号现在为0 [除非在BIOS中启用]。但是,其他CPUID部分可能提供一些独特性。以太网MAC地址 是唯一的,但许多NIC允许在软件中更改它。磁盘序列号不是一个好选择[IMO],因为磁盘的故障率最高,需要随时更换。

    但是,我们假设您可以从上述来源[以及其他一些人]收集足够的信息来获取“系统ID”。您可以将其与其他内容(如用户名等)连接起来。如果您选择,您可以通过sha1 [或其他]等单向哈希运行此方法。所以,现在,你已经拥有了“系统身份”。保存在某处(例如文件或注册表)

    但是,将私有密钥存储在应用程序[或客户端系统的任何位置]是非首发IMO。你只需要在生成阶段就这样做。

    因此,让注册过程将系统标识发送到您控制的私有服务器(例如Amazon EC2)。服务器使用公共/私有密钥加密(如RSA)加密/签署系统标识并发回公钥和“签名结果”。这些存储。

    任何应用程序的验证都是重新收集系统身份信息,应用算法和公钥。它应该与签名的结果匹配。

    这消除了将私钥与应用程序一起存储的需要,并使用使用RC4 [或等效]的密码对其进行加密。这消除了一开始就削弱了您的保护的复杂性。

    我对“系统管理员”或“串行许可证生成人员”感到有点困惑。如果那不是您[或您的服务器],那么它意味着您将发放OEM合同,并且本地管理员可以为此控制下的给定系统子集生成许可证。因此,您需要一个OEM密钥[发送到您的服务器]以允许生成多个许可证。

    现在,坏消息。

    任何软件许可方案都很容易破解。在应用程序中,无论验证算法有多复杂[或简单],它都归结为[或多个] go / nogo测试。就是这样:

    #include <stdlib.h>
    
    int user_authorized(void);
    void run_program();
    
    int
    main(void)
    {
    
        if (! user_authorized())
            abort();
    
        run_program();
    
        return 0;
    }
    

    这转换为:

        .globl  main
    main:
        subq    $8, %rsp
        call    user_authorized
        testl   %eax, %eax
        je      .L5                         # change this to a nop
        xorl    %eax, %eax
        call    run_program
        xorl    %eax, %eax
        addq    $8, %rsp
        ret
    .L5:
        call    abort
    

    注意je .L5中止程序。如果程序已修补以将此指令更改为nop,则无论user_authorized执行什么操作,许可证测试都会“通过”。

    对于与程序一样多的安全检查,可以重复此操作。

    安全是一个相对的术语。 50美元的应用程序不需要像售价500,000美元的应用程序那样多的保护(例如Xilinx的一些CAD / CAE程序)。

    从微软的剧本中摘取一页。它们提供了您必须接受的“许可”对话框(即“收缩包装”)。一个人必须接受协议。它禁止逆向工程等。这为您提供法律保障。请咨询律师。

    此外,这是您最终决定的软件方案。