我想将文件与我的软件一起发送,该文件的内容需要对我的软件用户隐藏(无法进行在线身份验证,因为该软件必须可以离线执行)。我这样做的方法是使用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个字符的长窗口,使用每个字符串解密文件,然后检查文件是否可以正确解析。
我知道,如果密钥以某种格式存在于源代码中,则不可能完全保护密钥,但是在这种情况下,可以使用哪些典型技术使攻击者的生活更艰难?
想到的显而易见的解决方案是将密钥拆分为多个子字符串,并将它们分散在整个代码中,或者在字符串中间插入虚拟字符,但是我对软件安全性的了解为零,所以这很好听听其他建议。
答案 0 :(得分:3)
对此有一个完整的研究领域,称为“ 白盒密码学”。只是用谷歌搜索。
一次解决方案是对AES使用白盒密码代码生成器。给定一个秘密密钥,它将为该特定密钥生成实现AES或AES部分的源代码。密钥间接嵌入在代码中。没有明确存储。
Whitebox-crypto-AES似乎就是这样的代码生成器。我没用过试试看...
答案 1 :(得分:0)
如果您使用的是DotNet技术(MS .Net或DotNet Core),则可以使用DPAPI保护此类密钥。
基本上,您首先使用密钥派生方法来派生/生成密钥,然后使用DPAPI将密钥保护在注册表或文件中。