java常量对抗字节码逆向工程

java常量对抗字节码逆向工程,java,string,encryption,reverse-engineering,bytecode,Java,String,Encryption,Reverse Engineering,Bytecode,我想知道我是否可以在编译的java文件中加密字符串。 例如,我需要用对称密钥解码zip文件,并且需要将该密钥存储在java类中的私有常量中: private static final String ZIP_PASSW="secret" 但我不希望一个简单的反向字节码显示原始密码。。。你认为有什么可以避免的吗 多谢各位 PS:我不明白为什么S.O.说如果没有这个PS,我的问题不符合其标准如何存储已经加密的密码 不,如果你存储了一个加密的密码,你仍然需要在某个时候对它进行解密,破解者只需反汇编你的

我想知道我是否可以在编译的java文件中加密字符串。 例如,我需要用对称密钥解码zip文件,并且需要将该密钥存储在java类中的私有常量中:

private static final String ZIP_PASSW="secret"
但我不希望一个简单的反向字节码显示原始密码。。。你认为有什么可以避免的吗

多谢各位


PS:我不明白为什么S.O.说如果没有这个PS,我的问题不符合其标准

如何存储已经加密的密码

不,如果你存储了一个加密的密码,你仍然需要在某个时候对它进行解密,破解者只需反汇编你的代码并找出算法,然后从中获得密码。

当你说你需要用对称密钥解码zip文件时,你确实需要这么做吗?与其考虑如何将密码存储为明文或如何对其进行编码之类的细节,您可能需要查看您的总体架构。例如,您的代码可能会调用安全的Web服务来获取密钥,而不是存储密钥?显然,如果没有更好地了解您的目标,就很难提出可行的替代方案,但您所描述的内容将很难保持适当的安全性-它将由于模糊而安全,但对于决心找到您的钥匙的人来说,它不会很强


如果这对于您需要执行的操作来说不够安全,那么最标准的响应可能是集成某种PGP密钥交换,而不是使用对称加密。

您可以做的最好的事情是使其更难访问。任何加密字符串都可以使用存储在代码中的密码进行解密。您可以采取措施隐藏密码,但使用私有常量不是此类措施之一。

真正的黑客仍然能够解密密码,但如果您不将密码存储为字符串文字,则可能会使解密更困难。您可以使用:

private static final String KEY = new String(new char[]{'s', 'e', 'c', 'r', 'e', 't'});
这将导致字节码:

javap -c -v TestObfuscate

static {};
  Code:
   Stack=6, Locals=0, Args_size=0
   0:   new #10; //class java/lang/String
   3:   dup
   4:   bipush  6
   6:   newarray char
   8:   dup
   9:   iconst_0
   10:  bipush  115
   12:  castore
   13:  dup
   14:  iconst_1
   15:  bipush  101
   17:  castore
   18:  dup
   19:  iconst_2
   20:  bipush  99
   22:  castore
   23:  dup
   24:  iconst_3
   25:  bipush  114
   27:  castore
   28:  dup
   29:  iconst_4
   30:  bipush  101
   32:  castore
   33:  dup
   34:  iconst_5
   35:  bipush  116
   37:  castore
   38:  invokespecial   #12; //Method java/lang/String."<init>":([C)V
   41:  putstatic   #16; //Field KEY:Ljava/lang/String;
   44:  return
返回

Constant pool:
const #8 = String   #9; //  secret
请注意,我没有调用常量
PASSWORD
ZIP\u PASSW
(如果字符串是公共的,这一点很重要)


作为替代方案或除此之外,您可以使用模糊处理工具,例如。

如果您将密钥存储在代码中,则可以通过反向工程随时检索密钥。此外,编译之前还是之后存储密钥也无关紧要

如果不可能对程序进行反向工程,就无法在程序中提供任何类型的(未加密的)密钥。这就是为什么非对称加密首先被发明的原因

因此,如果坚持使用对称加密,则必须将密钥存储在应用程序外部(例如文本文件中),并通过安全通道将文件传递给程序用户。(当然,他们可以任意使用钥匙)


如果这不是您想要的,您应该研究非对称加密技术。

公共字符串不是很好的主意:-)我喜欢这个解决方案…:-)我知道这不是很安全,但总比什么都好,JAD仍然会将其反编译成这样:
private static final String KEY=new String(new char[]{'s','e','c','r','e','t})
对于大多数反编译器来说,这不会有帮助,因为maksimov已经说过简单的算术(rot13、xor等)如何保护密钥不受第一个视图的影响?我必须创建一个DB转储文件,让用户备份外部内存中的所有数据。但是我不想要一个普通的文件…如果你的用户上传了一个公钥,那么你可以加密数据,但是没有私钥你就无法解密。他们下载加密后可以随意解密。我不明白为什么非对称密钥可以解决我的问题。。。我仍然需要将私钥存储在我的代码中,还是我错了?非对称密钥只需要私钥进行解密,因此如果您有公钥但没有解密,则可以进行加密。显然,需要一个精明的用户或某种类型的客户机来管理解密,但你从不存储私钥——只存储公共密钥。我认为这是一个好问题,在某些情况下,异步加密(正如这里每个人都在尖叫的那样)对解决这个问题没有多大帮助。例如,当您希望在应用程序数据库中存储用户指定的密码时,您需要能够以明文形式检索该密码,但不希望将其以明文形式存储在数据库中。因此,您的应用程序必须能够对其进行加密和解密=>您将遇到与必须提供的密钥相同的问题(分别是异步加密的两个密钥)。无论您是否使用同步作为AES。
Constant pool:
const #8 = String   #9; //  secret