我想随我的软件一起发送一个文件,该文件的内容需要对我的软件用户隐藏(在线身份验证是不可能的,因为软件需要离线执行(。我这样做的方法是使用 AES-256 加密文件,然后将加密密钥存储在源文件中。事实证明,从编译的可执行文件中恢复此密钥非常容易,因为整个字符串只是位于一个连续的块中。以下 Python 代码查找密钥:
with open("/path/to/executable", 'rb') as readfile:
content = readfile.read()
to_find = 'C0SH3VKNTKR4CRGH0R8WXD9WR5I1GS' # example key
for i in range(len(content) - len(to_find)):
substr = content[i:i + len(to_find)]
if substr == to_find:
print "Found at index %d" % i
当然,作为一个攻击者,我不知道我在搜索什么。但是,通过查看可执行文件所依赖的共享库,可以很容易地推断出解密文件的所需格式(这些库是开源的,解密文件的格式也是一种广泛使用的标准(。所以基本上,人们可以在构成可执行文件的二进制内容上滑动一个 30 个字符长的窗口,使用每个字符串解密文件,然后检查它是否可以正确解析。
我知道如果密钥以某种格式存在于源代码中,则不可能完全保护该密钥,但是在这种情况下,可以使用哪些典型技术来使攻击者的生活更加困难?
想到的明显解决方案是将密钥拆分为多个子字符串并将它们分散在整个代码中,或者在字符串中间插入虚拟字符,但我对软件安全的知识为零,所以很高兴听到其他建议。
有一个完整的研究领域称为白盒密码学。只是谷歌它。
其中一个选项是为AES 使用白盒加密代码生成器。给定一个密钥,它将生成实现AES的源代码或该特定密钥的AES的一部分。密钥间接嵌入在代码中。它未显式存储。
似乎Whitebox-crypto-AES就是这样一个代码生成器。我从来没有用过它。试一试...
如果您使用的是DotNet技术(MS .Net或DotNet Core(,则可以使用DPAPI保护此类密钥。
本质上,您使用密钥派生方法在首次使用时派生/生成密钥,然后使用 DPAPI 保护注册表或文件中的密钥。