关于java:如何保护MySQL用户名和密码不被反编译?

How can I protect MySQL username and password from decompiling?

Java EDCOX1的0个文件可以很容易地反编译。如果必须在代码中使用登录数据,我如何保护我的数据库?


不要将密码硬编码到代码中。这是最近在25个最危险的编程错误中提到的:好的。

Hard-coding a secret account and
password into your software is
extremely convenient -- for skilled
reverse engineers. If the password is
the same across all your software,
then every customer becomes vulnerable
when that password inevitably becomes
known. And because it's hard-coded,
it's a huge pain to fix.

Ok.

您应该将配置信息(包括密码)存储在应用程序启动时读取的单独文件中。这是防止由于反编译而导致密码泄漏的唯一真正方法(不要首先将其编译成二进制文件)。好的。

关于这个常见错误的更多信息,您可以阅读CWE-259文章。这篇文章包含了一个更深入的定义、例子和许多关于这个问题的其他信息。好的。

在Java中,最简单的方法之一就是使用首选项类。它被设计用来存储各种程序设置,其中一些设置可能包括用户名和密码。好的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.prefs.Preferences;

public class DemoApplication {
  Preferences preferences =
      Preferences.userNodeForPackage(DemoApplication.class);

  public void setCredentials(String username, String password) {
    preferences.put("db_username", username);
    preferences.put("db_password", password);
  }

  public String getUsername() {
    return preferences.get("db_username", null);
  }

  public String getPassword() {
    return preferences.get("db_password", null);
  }

  // your code here
}

在上面的代码中,您可以在显示一个对话框询问用户名和密码后调用setCredentials方法。当需要连接到数据库时,只需使用getUsernamegetPassword方法来检索存储的值。登录凭据不会硬编码到二进制文件中,因此反编译不会带来安全风险。好的。

重要提示:首选项文件只是纯文本XML文件。确保采取适当的步骤防止未经授权的用户查看原始文件(Unix权限、Windows权限等)。至少在Linux中,这不是问题,因为调用Preferences.userNodeForPackage将在当前用户的主目录中创建XML文件,其他用户无论如何都无法读取该文件。在Windows中,情况可能不同。好的。

更重要的是:在这个答案的评论中,以及其他一些关于这个情况下正确的架构是什么的讨论很多。最初的问题并没有真正提到应用程序使用的上下文,所以我将讨论我能想到的两种情况。第一种情况是,使用程序的人已经知道(并且有权知道)数据库凭据。第二种情况是,在这种情况下,开发人员试图对使用程序的人保密数据库凭据。好的。

第一种情况:用户有权知道数据库登录凭据好的。

在这情况下,将上述溶液在以上工作。《Java类Preference《威尔和密码username可存储在纯文本文件,但偏好将只读和读的授权用户。用户可以简单的打开XML文件的读和偏好的登录凭据,但这是不是一个安全的风险,因为我知道这两个用户的凭据与开始。

好。

案例二:想隐藏从用户的登录凭据

好。

这是在更复杂的案例:"应该不知道用户的登录凭据,但仍然需要访问的数据库。在这情况下,用户运行的应用程序有两个直接存取数据库的程序,这需要两个均值的登录凭据。太可怕了。在上述的解决方案是不合适的,超过这个案例。你可以在大的数据库登录凭据的通知文件,但他的用户将能够读这两个文件,因为他们将是主人。事实上,有很多不好的方式使用这两个案例在一个安全的方式。

好。

正确的案例:采用多层体系结构

好。

"正确的方式做它是两个有一个中间层之间,在你和你的数据库服务器,客户端应用程序,允许用户authenticates个体和A公司的两个performed作战。每个用户将他们自己的登录凭据,但不是在数据库服务器。《凭据将允许访问的中间层的业务逻辑层)和将是不同的为每个用户。

好。

每一个用户将他们自己的username和密码,这可能是局部可存储在一个文件的通知"没有任何安全风险。这是一个所谓的三层体系结构(《有你的数据库服务器层、业务逻辑服务器和客户端应用程序)。它是更复杂的,但它真的是最安全的方式是这样做的事。

好。

《冰阶(Basic操作:

好。

  • 客户机使用用户的个人用户名/密码对业务逻辑层进行身份验证。用户名和密码是用户已知的,与数据库登录凭据没有任何关系。
  • 如果认证成功,客户机向业务逻辑层发出请求,请求从数据库中获取一些信息。例如,产品库存。注意,客户机的请求不是SQL查询;它是一个远程过程调用,如getInventoryList
  • 业务逻辑层连接到数据库并检索请求的信息。业务逻辑层负责根据用户的请求形成安全的SQL查询。应该清理SQL查询的所有参数,以防止SQL注入攻击。
  • 业务逻辑层将库存列表发送回客户机应用程序。
  • 客户机向用户显示库存列表。
  • 注意,在整个过程中,客户机应用程序从不直接连接到数据库。业务逻辑层接收来自经过身份验证的用户的请求,处理客户机对清单列表的请求,然后只执行SQL查询。好的。好啊.


    将密码放入应用程序将读取的文件中。不要在源文件中嵌入密码。期间。

    对于这种用法,Ruby有一个鲜为人知的模块dbi::dbrc。我毫不怀疑Java有一个等价物。不管怎样,写一本并不难。


    您正在编写Web应用程序吗?如果是这样,请使用JNDI在应用程序外部配置它。此处提供概述:

    JNDI provides a uniform way for an
    application to find and access remote
    services over the network. The remote
    service may be any enterprise service,
    including a messaging service or an
    application-specific service, but, of
    course, a JDBC application is
    interested mainly in a database
    service. Once a DataSource object is
    created and registered with a JNDI
    naming service, an application can use
    the JNDI API to access that DataSource
    object, which can then be used to
    connect to the data source it
    represents.


    无论您做什么,敏感信息都将存储在某个文件中的某个位置。你的目标是尽可能地让它变得困难。这其中有多少可以实现取决于你的项目、需求和你公司钱包的厚度。

    最好的方法是不要在任何地方存储任何密码。这是通过使用哈希函数生成和存储密码哈希来实现的:

    1
    2
    hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
    hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366

    Hash algorithms are one way functions. They turn any amount of data
    into a fixed-length"fingerprint" that cannot be reversed. They also
    have the property that if the input changes by even a tiny bit, the
    resulting hash is completely different (see the example above). This
    is great for protecting passwords, because we want to store passwords
    in a form that protects them even if the password file itself is
    compromised, but at the same time, we need to be able to verify that a
    user's password is correct.

    不相关的说明:在互联网的旧时代,当你点击"忘记我的密码"链接时,网站会通过电子邮件向你发送你的纯文本密码。他们可能把它们存储在数据库的某个地方。当黑客访问他们的数据库时,他们将获得所有密码的访问权。由于许多用户会在多个网站中使用相同的密码,这是一个巨大的安全问题。幸运的是,现在这不是常见的做法。

    现在问题来了:存储密码的最佳方法是什么?我认为这个(身份验证和用户管理服务StormPath)解决方案非常理想:

  • 您的用户输入凭据,并根据密码哈希
  • 密码散列是生成和存储的,而不是密码
  • 哈希执行多次
  • 哈希是使用随机生成的salt生成的
  • 哈希使用私钥加密
  • 私钥存储在物理上与哈希不同的位置
  • 私钥采用基于时间的方式更新
  • 加密哈希被分成块
  • 这些块存储在物理上独立的位置
  • 很明显你不是谷歌或者银行,所以这对你来说是一个致命的解决方案。但问题来了:你的项目需要多少安全保障,你有多少时间和金钱?

    对于许多应用程序,尽管不推荐,但在代码中存储硬编码密码可能是一个很好的解决方案。但是,通过从上面的列表中轻松地添加两个额外的安全步骤,您可以使应用程序更加安全。

    例如,假设步骤1不是项目可接受的解决方案。您不希望用户每次都输入密码,或者您甚至不希望/不需要用户知道密码。但你还是有一些敏感的信息,你想保护它。你有一个简单的应用程序,没有服务器来存储你的文件,或者这对你的项目来说太麻烦了。您的应用程序运行在无法安全存储文件的环境中。这是最坏的情况之一,但是有了一些额外的安全措施,您就可以得到更安全的解决方案。例如,您可以将敏感信息存储在一个文件中,并且可以加密该文件。您可以在代码中硬编码加密私钥。你可以混淆代码,所以你让别人破解代码有点困难。为此目的存在许多库,请参见此链接。(我想再次警告您,这不是100%安全的。一个拥有正确知识和工具的聪明黑客可以破解这个问题。但根据您的需求和需要,这可能是一个很好的解决方案。


    这个问题展示了如何在加密文件中存储密码和其他数据:基于Java 256位AES的基于密码的加密


    MD5是一个哈希算法,不是一个加密算法,简而言之,U不能得到回W U哈希,U只能比较。在存储用户身份验证信息时最好使用它,而不是数据库用户名和密码。数据库用户名和pwd应该加密并保存在一个配置文件中,这样做最少。