【问题标题】:How to make a static string not visible while encounter disassembling?遇到反汇编时如何使静态字符串不可见?
【发布时间】:2012-04-24 03:32:16
【问题描述】:

我从第三方供应商处获得了几个许可证密钥,这些密钥已授权给我的移动应用程序(C/C++ 语言),为了不泄露给外界,供应商需要检查我的代码以确保这些密钥被加密以防止反汇编。

我得到的最初方法是加密(使用可逆加密方法)这些密钥并在使用时对其进行解密,但这不是最终的解决方案,极端地说,可以通过反转我的代码来解密它。

供应商推荐使用reverse hash来加密这些key(我不知道reverse hash),有没有其他选择(简单,易于实现但更难反汇编)我可以将这些键隐藏在我的代码中以防止反汇编?

【问题讨论】:

  • 供应商的意思可能是可逆散列函数?普通哈希是单向的:您可以对字符串进行哈希处理,但要从结果中恢复它们会非常困难。
  • 是的,我用谷歌搜索了所有的哈希算法,没有一个哈希算法是可逆的(或者非常非常难以逆转),我不知道如何将其设为 reverse hash 以获得解决方案。 ..
  • @coanor 嗯,哈希算法的重点是它们是不可逆的,因为几乎任何哈希算法都意味着数据丢失。
  • 如果供应商要求他们满意地隐藏密钥,那么他们肯定有一些示例代码来说明他们希望您如何做到这一点吗?这样您就不必猜测它是否对他们“足够好”。

标签: c public-key-encryption password-encryption


【解决方案1】:

你可以让倒车变得更加困难,但你无法阻止它。无论您选择何种加密方式,黑客都可以从您的程序中获取密钥,因为您的程序会解密密钥以进行许可证检查。

黑客也可以破坏 3-rd 方库而不是窃取您的密钥 :)

我会向库供应商索取代码示例,说明如何保护密钥以满足他们的要求。

顺便有个关于 SO 上的可逆哈希的问题:Reversible hash function?

【讨论】:

    【解决方案2】:

    没有“反向哈希算法”这样的东西。任何散列算法都被设计为单向的并且意味着数据的丢失。如果是双向的,则称为密码。

    只要用户能够运行您的应用程序,并且应用程序在某些时候使用这些密钥,这些密钥就可能会泄露。这可以通过反汇编和逆向工程、从内存中转储密钥或运行调试器来完成。因此,您能做的最好的事情就是以某种方式对其进行加密,并使其尽可能不明显地解密。

    鉴于您是为移动平台编写的,您可能会尝试依赖某些操作系统机制来保护密钥。或者,如果这些是某些 Web API 的密钥,您可以设置一个服务器来存储这些密钥并作为代理工作。或者实际上向您的第三方供应商询问他们在保护密钥方面的最佳做法以及具体的实施细节,例如建议的加密机制。

    【讨论】:

      【解决方案3】:

      假设您将拥有这样的代码:

      unsigned char *bytes;
      some_extremely_complicated_function_which_decrypt_key(bytes);
      add_some_confusing_things();
      maybe_even_split_into_several_calls(bytes);
      // ...
      call_function_using_their_key(bytes,data1,data2,data3);
      

      这将导致汇编程序如下所示:

      push [ebp+0004h]  // data3
      push ecx          // data2
      push [ebp+0024h]  // data1
      push [eax]        // key (bytes)
      call 123456h      // call to call_function_using_their_key
      

      您几乎总能从导入/重定位表中获得call_function_using_their_key 的地址(除非它是内联的、非常难以混淆的或很少有类似的技术)。

      我会简单地为每个call 123456h 自动添加断点,最后一次按下 = 键,键指向内存地址543216h,从543216h 获取键。

      任何加密都是无用的。

      故事的寓意:首先确保他们的 API 对加密数据有意义,否则你会很擅长这个:

      char *globalBytesPtr;
      
      int main(){
          globalBytesPtr = malloc(N);
          globalBytesPtr[8] = 0x35;
          globalBytesPtr[3] = 0x14;
          globalBytesPtr[5] = 0x20;
          ...
      }
      

      因此,您的密钥不会出现在静态转储中。这不会降低安全性,因为最薄弱的环节是他们的 API 调用,您无法让应用程序在这个世界中更安全。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 2014-05-06
        相关资源
        最近更新 更多