我从第三方供应商处获得了几个许可证密钥,这些密钥已授权给我的移动应用程序(C/C++ 语言),为了不泄露给外界,供应商需要检查我的代码以确保这些密钥已加密以防止拆卸。
我得到的最初方法是加密(使用可逆加密方法)这些密钥并在使用时解密,但这不是最终的解决方案,极端地说,可以通过反转我的代码来解密它。
供应商建议使用反向哈希来加密这些密钥(我不知道反向哈希),还有其他选择(简单,易于实现但难以反汇编)我可以将这些密钥隐藏在我的代码中以防止反汇编吗?
我从第三方供应商处获得了几个许可证密钥,这些密钥已授权给我的移动应用程序(C/C++ 语言),为了不泄露给外界,供应商需要检查我的代码以确保这些密钥已加密以防止拆卸。
我得到的最初方法是加密(使用可逆加密方法)这些密钥并在使用时解密,但这不是最终的解决方案,极端地说,可以通过反转我的代码来解密它。
供应商建议使用反向哈希来加密这些密钥(我不知道反向哈希),还有其他选择(简单,易于实现但难以反汇编)我可以将这些密钥隐藏在我的代码中以防止反汇编吗?
你可以让倒车变得更加困难,但你无法阻止它。无论您选择何种加密方式,黑客都可以从您的程序中获取密钥,因为您的程序会解密密钥以进行许可证检查。
黑客也可以破坏 3-rd 方库而不是窃取您的密钥 :)
我会向图书馆供应商索取代码示例,以展示如何保护密钥以满足他们的要求。
顺便说一下关于 SO: Reversible hash function 的可逆哈希的问题?
没有“反向哈希算法”之类的东西。任何散列算法都被设计为单向的并且意味着数据的丢失。如果是双向的,则称为密码。
只要用户能够运行您的应用程序,并且应用程序在某些时候使用这些密钥,这些密钥就可能会泄露。这可以通过反汇编和逆向工程、从内存中转储密钥或运行调试器来完成。因此,您能做的最好的事情就是以某种方式对其进行加密,并使其尽可能不明显地解密。
鉴于您正在为移动平台编写它,您可能会尝试依赖某些操作系统机制来保护密钥。或者,如果这些是某些 Web API 的密钥,您可以设置一个服务器来存储这些密钥并作为代理工作。或者实际上向您的第三方供应商询问他们保护密钥的最佳实践以及特定的实施细节,例如建议的加密机制。
假设您将拥有这样的代码:
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
从导入/重定位表中获取地址(除非它是内联的、非常难以混淆的或很少有类似的技术)。
我只是自动添加断点到 each call 123456h
, last push = key, key pointing to memory address 543216h
, get key from 543216h
.
任何加密都是无用的。
故事的寓意:首先确保他们的 API 对加密数据有意义,否则你会很好的:
char *globalBytesPtr;
int main(){
globalBytesPtr = malloc(N);
globalBytesPtr[8] = 0x35;
globalBytesPtr[3] = 0x14;
globalBytesPtr[5] = 0x20;
...
}
因为这样你的密钥就不会出现在静态转储中。这不会降低安全性,因为最薄弱的地方是他们的 API 调用,你不能让应用程序在这个宇宙中更安全。