如何保护解密密钥免受反编译?

6
我是一名初级的Java程序员。我正在开发一个解密一些数据的应用程序。
这个解密密钥是硬编码进软件中的,因此可以通过分析字节码来查看。
我知道无法完全防止反向工程,所以我试图使这个过程尽可能地困难。
我的想法不是直接将密钥放入我的代码中,而是让它经过某种转换。
例如,我可以写 -
private static final byte[] HC256A = Hex
            .decode("8589075b0df3f6d82fc0c5425179b6a6"
                    + "3465f053f2891f808b24744e18480b72"
                    + "ec2792cdbf4dcfeb7769bf8dfa14aee4"
                    + "7b4c50e8eaf3a9c8f506016c81697e32");

这样,查看字节码的人就无法直接阅读它。但是必须按照逻辑进行转换,这在字节级别上并不容易。

那么你们认为这有用吗?除了十六进制解码之外,最好的转换是什么?是否有其他可用于保护硬编码解密密钥的方法?

感谢您所有的建议。


2
你可以监听调试器的连接(在C++中有效,不确定如何在Java中实现),如果连接成功,则从内存中删除该值。 - Kajetan Abt
数据解码的敏感度是多少?这将有助于作为指南,以确定保护该数据所需付出的努力。任何形式的在字节码中隐藏密钥都相对容易被攻破。此外,这将要求软件的每个用户都具有相同的密钥,并且需要重新编译才能更改密钥。 - this.josh
数据非常敏感。这是数字媒体印刷品,如果泄露将会给公司带来严重问题。 - Monika Michael
3个回答

8

攻击这种混淆(特别是在字节码语言中)的正确方法是将调试器附加到传递密钥的位置(如果无法调试,则从该位置开始分析代码)。这样,攻击者根本不需要查找密钥,也不关心密钥有多么混淆。因此,您需要重新考虑设计。

如果您只想保护自己免受业余窥视者的侵害,那么将密钥分割并对其部分进行异或(可能使用不同的密钥)就足够了。还有一个诀窍——从代码中已经存在的文本常量(例如应用程序名称)派生密钥。这使密钥比分裂或异或更不明显。


请翻译以下与编程有关的内容,从英文到中文。仅返回翻译后的文本:+1 分用于回答「为什么不应该这样做」和「如何才能实现」两个问题 ;-) - Joachim Sauer
@Joachim 实际上这两部分涵盖了不同的攻击者集合 :) - Eugene Mayevski 'Callback

3
不要将密钥直接编码进源代码中。将其与源代码分开,单独交付,例如放在Java密钥库中,并仅提供给您信任的客户/站点/客户端,在许可证中加入一些法律条款,如果他们泄漏了密钥库,则由他们承担责任。

0
面对类似的问题(在C语言中),我选择了单次使用的异或加密密钥。这种方法很好,因为它看起来像垃圾...如果你非常聪明,你可以窃听正在使用的(不正确的)密钥。我建议避免注入人类可读的字符串,因为这些通常会引起代码的注意。

2
XOR 填充加上一些位移应用可能是最好的解决方案:它并不是真正的“好”预防措施,但它能挫败那些简单地调用 javah 并希望获得密钥直接转储的人。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接