2011-05-20 148 views
6

我是一个初学java程序员。我正在研究解密一些数据的应用程序。 解密密钥被硬编码到软件中,因此可以通过分析字节码来查看。如何保护解密密钥免遭反编译?

我知道逆向工程不可能完全被阻止,所以我想要做的是尽可能地让这个过程变得困难。

我的想法不是直接将密钥放入我的代码中,而是让它通过某种转换。 例如,我可以写 -

private static final byte[] HC256A = Hex 
      .decode("8589075b0df3f6d82fc0c5425179b6a6" 
        + "3465f053f2891f808b24744e18480b72" 
        + "ec2792cdbf4dcfeb7769bf8dfa14aee4" 
        + "7b4c50e8eaf3a9c8f506016c81697e32"); 

这样,有人在看字节码不能读它,立竿见影。但是必须遵循逻辑并对其应用转换,在字节级别上这不会更容易。

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

感谢您的所有建议。

+2

您可以侦听连接的调试器(以C++工作,不知道如何在Java中执行该操作),如果是这样,请从内存中删除该值。 – 2011-05-20 09:30:56

+0

正在解码的数据的灵敏度是什么?这将有助于为保护数据付出多少努力提供指导。隐藏字节码中任何形式的密钥都相对容易失败。此外,这需要软件的每个用户拥有相同的密钥,并且需要重新编译才能更改密钥。 – 2011-05-21 06:50:56

+0

数据非常敏感。这是一个数字媒体印刷品,如果泄漏会给公司带来严重问题。 – 2011-06-17 13:44:23

回答

8

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

如果你只想保护业余爱好者,那么拆分键和异或元件(可能用不同的键)就足够了。还有一个窍门 - 从代码中已经存在的文本常量(例如应用程序名称)中派生出密钥。这使得关键不如分裂或XORing更明显。

+1

+1为'派生关键' – sehe 2011-05-20 09:44:21

+0

+1为回答**两个**为什么你不应该这样做**和**如何做到这一点;-) – 2011-05-23 06:05:22

+0

@Joachim实际上这两个部分涵盖了不同组的攻击者:) – 2011-05-23 06:18:37

0

面对类似的问题(在c)我去了一次性XOR垫。这很好,因为它看起来像垃圾......如果你真的聪明,你可以窥探使用中的(不正确)键。我会避免任何注入人类可读字符串的东西,因为这些东西总是会引起人们对代码的注意。

+2

应用了一些位移功能的XOR焊盘可能与其获得的效果一样好:它并不是很好的预防措施,但它会阻止那些简单地称为javah的用户,并希望能够直接转储密钥。 – 2011-05-20 09:37:22

3

不要将密钥编码到源代码中。保持分开,单独运送,例如在Java密钥仓库中,并且仅限于您信任的客户/站点/客户端,并在许可证中放置一些法律术语,以便在泄漏密钥存储库时将责任置于其上。

+0

如何将密钥存储在密钥库中? – raymi 2011-10-26 11:39:03