我需要在我的C++应用程序中存储敏感信息(我想保持私有的对称加密密钥)。简单的方法是这样做:
std::string myKey = "mysupersupersecretpasswordthatyouwillneverguess";
但是,通过strings
进程(或从二进制应用程序中提取字符串的任何其他程序)运行应用程序将显示上述字符串。
应该使用什么技术来掩盖这样的敏感数据?
编辑:
好吧,所以几乎所有的人都说过“你的可执行文件可以反向工程”--当然!这是我的宠物,所以我要在这里咆哮一下:
为什么99% (好吧,也许我夸大了一点)在这个网站上的所有与安全相关的问题的答案是“没有可能的方法来创建一个完全安全的程序”-这不是一个有用的答案!安全性是在完全可用性和无安全性之间的滑动尺度,而在另一端则是完全安全但没有可用性之间的滑动尺度。
关键是你选择你的位置在那个滑动尺度上取决于你想要做什么和你的软件将在什么环境中运行。我不是在为军事安装编写应用程序,而是在为家用PC编写应用程序。我需要使用预先知道的加密密钥,通过不可信的网络加密数据。在这种情况下,“通过默默无闻的安全性”可能已经足够了!当然,有足够的时间、精力和技能的人可以反向设计二进制文件并找到密码,但你猜怎么着?我不在乎:
实现一个一流的安全系统所需的时间要比由于破解版本而导致的销售损失更昂贵(并不是说我实际上是在卖这个,但你明白我的意思)。这种蓝蓝的“让它以绝对最好的方式去做”的趋势在新程序员中是愚蠢的。
谢谢你抽出时间回答这个问题--它们非常有用。不幸的是,我只能接受一个答案,但我对所有有用的答案都投了赞成票。
发布于 2009-10-30 00:37:04
基本上,任何能够访问您的程序和调试器的人都可以在应用程序中找到密钥,如果他们愿意的话。
但是,如果您只想确保在您的二进制文件上运行strings
时键没有显示出来,那么您可以确保键不在可打印的范围内。
用异或隐藏密钥
例如,可以使用XOR将键拆分为两个字节数组:
key = key1 XOR key2
如果创建key1的字节长度与key
相同,则可以使用(完全)随机字节值,然后计算key2
。
key1[n] = crypto_grade_random_number(0..255)
key2[n] = key[n] XOR key1[n]
您可以在构建环境中这样做,然后只在应用程序中存储key1
和key2
。
保护二进制
另一种方法是使用工具来保护二进制文件。例如,有几个安全工具可以确保二进制文件被混淆,并启动运行它的虚拟机。这使得调试变得非常困难,而且也是许多商业级安全应用程序(唉,恶意软件)受到保护的通常方式。
西米达是最重要的工具之一,它在保护二进制文件方面做得很棒。它经常被众所周知的程序使用,如Spotify,以防止逆向工程。它有防止调试的功能,如OllyDbg和Ida。
还有一个更大的列表,也许有点过时,保护二进制文件的工具。
其中一些是免费的。
密码匹配
这里有人讨论了哈希password+salt。
如果您需要将密钥与某种用户提交的密码相匹配,则应该使用单向散列函数,最好将用户名、密码和salt组合在一起。但是,这方面的问题是,您的应用程序必须知道salt才能进行单向操作并比较结果的散列。因此,您仍然需要在应用程序中的某个地方存储盐。但是,正如@Edward在下面的评论中所指出的,这将有效地防止字典攻击,例如使用彩虹表。
最后,您可以使用上述所有技术的组合。
发布于 2009-10-30 00:55:23
首先,要意识到你所能做的任何事情都无法阻止一个有足够决心的黑客,而且周围也有很多黑客。每一个游戏和控制台的保护最终都会被破解,所以这只是一个暂时的修复。
有4件事你可以做,这会增加你隐藏一段时间的机会。
1)以某种方式隐藏字符串的元素--类似xoring (^运算符)之类的明显内容--带有另一个字符串的字符串将足以使字符串无法搜索。
2)将字符串分成几个部分--将字符串拆分,并在奇怪的模块中弹出其中的一些奇怪的命名方法。不要让搜索和查找包含字符串的方法变得容易。当然,有些方法必须调用所有这些比特,但这仍然会使其变得更加困难。
3)永远不要在内存中构建字符串--大多数黑客使用的工具是,在您对字符串进行编码之后,可以让他们看到内存中的字符串。如果可能的话,避免这样做。例如,如果您要将键发送到服务器,则逐个字符发送该键,因此整个字符串永远不会出现。当然,如果您是从RSA编码之类的东西使用它,那么这就更棘手了。
4)做一个特别的算法--在所有这些基础上,增加一个或两个独特的转折。也许只要在你生产的东西上加1,或者做两次加密,或者加糖。这只会让那些已经知道当有人使用普通md5哈希或RSA加密时能找到什么的黑客变得更加困难。
最重要的是,当发现您的密钥时(如果您的应用程序变得足够受欢迎),确保它不太重要!
发布于 2020-05-02 08:15:22
有一个(非常轻的)只有头的项目模糊由阿达默克斯利制作,工作非常完美。它基于lambda函数和宏,在编译时使用XOR密码对字符串litteral进行加密。如果需要,我们可以更改每个字符串的种子。
下面的代码不会将字符串"hello world“存储在已编译的二进制文件中。
#include "obfuscate.h"
int main()
{
std::cout << AY_OBFUSCATE("Hello World") << std::endl;
return 0;
}
我已经用c++17和VisualStudio2019进行了测试,并通过IDA进行了检查,确认字符串是隐藏的。与ADVobfuscator相比,一个宝贵的优势是它可以转换为std::string (同时仍然隐藏在编译的二进制文件中):
std::string var = AY_OBFUSCATE("string");
https://stackoverflow.com/questions/1648618
复制