如何保护MySQL用户名和密码不被反编译? [英] How can I protect MySQL username and password from decompiling?

查看:1044
本文介绍了如何保护MySQL用户名和密码不被反编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java .class 文件可以相当容易地反编译。如果我必须在代码中使用登录数据,我该如何保护我的数据库?

Java .class files can be decompiled fairly easily. How can I protect my database if I have to use the login data in the code?

推荐答案

永远不要将密码硬编码到你的码。最近在 25个最危险的编程错误

Never hard-code passwords into your code. This was brought up recently in the Top 25 Most Dangerous Programming Mistakes:


在您的软件中对一个秘密帐户和
密码进行硬编码是非常方便的

逆向工程师。如果所有软件的密码都是
相同,那么每个客户在该密码不可避免地变为
时就会变得脆弱
。而且因为它是硬编码的,所以修复它是一件非常痛苦的事。

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.

你应该存储配置信息,包括密码,在应用程序启动时读取的单独文件中。这是防止密码因反编译而泄漏的唯一真正方法(永远不要将其编译成二进制文件开始)。

You should store configuration information, including passwords, in a separate file that the application reads when it starts. That is the only real way to prevent the password from leaking as a result of decompilation (never compile it into the binary to begin with).

有关此常见问题的更多信息错误,您可以阅读 CWE-259文章。本文包含更全面的定义,示例以及有关该问题的许多其他信息。

For more information about this common mistake, you can read the CWE-259 article. The article contains a more thorough definition, examples, and lots of other information about the problem.

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

In Java, one of the easiest ways to do this is to use the Preferences class. It is designed to store all sorts of program settings, some of which could include a username and password.

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 方法。当您需要连接到数据库时,您只需使用 getUsername getPassword 方法来检索存储的值。登录凭证不会硬编码到您的二进制文件中,因此反编译不会带来安全风险。

In the above code, you could call the setCredentials method after showing a dialog askign for the username and password. When you need to connect to the database, you can just use the getUsername and getPassword methods to retrieve the stored values. The login credentials will not be hard-coded into your binaries, so decompilation will not pose a security risk.

重要说明:首选项文件只是纯文本XML文件。确保采取适当措施防止未经授权的用户查看原始文件(UNIX权限,Windows权限等)。至少在Linux中,这不是问题,因为调用 Preferences.userNodeForPackage 将在当前用户的主目录中创建XML文件,这是其他人不可读的用户无论如何。在Windows中,情况可能会有所不同。

Important Note: The preference files are just plain text XML files. Make sure you take appropriate steps to prevent unauthorized users from viewing the raw files (UNIX permissions, Windows permissions, et cetera). In Linux, at least, this isn't a problem, because calling Preferences.userNodeForPackage will create the XML file in the current user's home directory, which is non-readable by other users anyway. In Windows, the situation might be different.

更多重要说明:在此答案的评论和其他评论中进行了大量讨论关于这种情况的正确架构是什么。最初的问题并没有真正提到应用程序的使用环境,所以我将谈谈我能想到的两种情况。第一种情况是使用该程序的人已经知道(并且被授权知道)数据库凭证。第二种情况是,您(开发人员)正在尝试保护数据库凭据对使用该程序的人保密。

More Important Notes: There has been a lot of discussion in the comments of this answer and others about what the correct architecture is for this situation. The original question doesn't really mention the context in which the application is being used, so I will talk about the two situations I can think of. The first is the case in which the person using the program already knows (and is authorized to know) the database credentials. The second is the case in which you, the developer, are trying to keep the database credentials secret from the person using the program.

第一种情况:用户是授权知道数据库登录凭据

在这种情况下,我上面提到的解决方案将起作用。 Java 首选项类将以纯文本格式存储用户名和密码,但首选项文件只能由授权用户读取。用户只需打开首选项XML文件并阅读登录凭据,但这不是安全风险,因为用户知道要开头的凭据。

In this case, the solution I mentioned above will work. The Java Preference class will stored the username and password in plain text, but the preferences file will only be readable by the authorized user. The user can simply open the preferences XML file and read the login credentials, but that is not a security risk because the user knew the credentials to begin with.

第二种情况:尝试隐藏用户的登录凭据

这是更复杂的情况:用户不应该知道登录凭据但仍需要访问权限数据库。在这种情况下,运行应用程序的用户可以直接访问数据库,这意味着程序需要提前知道登录凭据。我上面提到的解决方案不适合这种情况。您可以将数据库登录凭据存储在首选项文件中,但是用户将能够读取该文件,因为它们将是所有者。事实上,确实没有好办法以安全的方式使用这种情况。

This is the more complicated case: the user should not know the login credentials but still needs access to the database. In this case, the user running the application has direct access to the database, which means the program needs to know the login credentials ahead of time. The solution I mentioned above is not appropriate for this case. You can store the database login credentials in a preferences file, but he user will be able to read that file, since they will be the owner. In fact, there is really no good way to use this case in a secure way.

正确案例:使用多层架构

正确的方法是在数据库服务器和客户端应用程序之间建立一个中间层,用于对单个用户进行身份验证,并允许一组有限的操作执行。每个用户都有自己的登录凭据,但不适用于数据库服务器。凭证将允许访问中间层(业务逻辑层),并且对于每个用户将是不同的。

The correct way to do it is to have a middle layer, in between your database server and your client application, that authenticates individual users and allows a limited set of operations to be performed. Each user would have their own login credentials, but not for the database server. The credentials would allow access to the middle layer (the business logic tier) and would be different for each user.

每个用户都有自己的用户名和密码,这可能是存储在首选项文件中,没有任何安全风险。这称为三层架构(这些层是您的数据库服务器,业务逻辑服务器和客户端应用程序)。它更复杂,但它确实是最安全的方式来做这类事情。

Every user would have their own username and password, which could be stored locally in a preferences file without any security risk. This is called a three-tier architecture (the tiers being your database server, business logic server, and client application). It is more complex, but it really is the most secure way to do this sort of thing.

基本的操作顺序是:


  1. 客户端使用用户的个人用户名/密码对业务逻辑层进行身份验证。用户名和密码是用户已知的,并且与数据库登录凭据无关。

  2. 如果身份验证成功,客户端会向业务逻辑层发出请求,要求提供一些来自数据库的信息。例如,产品清单。请注意,客户端的请求不是SQL查询;它是一个远程过程调用,例如 getInventoryList

  3. 业务逻辑层连接到数据库并检索所请求的信息。业务逻辑层负责根据用户的请求形成安全的SQL查询。应该清理SQL查询的任何参数以防止SQL注入攻击。

  4. 业务逻辑层将库存列表发送回客户端应用程序。

  5. 客户端向用户显示库存清单。

  1. Client authenticates with business logic tier using the user's personal username/password. The username and password are known to the user and are not related to the database login credentials in any way.
  2. If authentication succeeds, the client makes a request to the business logic tier asking for some information from the database. For example, an inventory of products. Note that the client's request is not a SQL query; it is a remote procedure call such as getInventoryList.
  3. The business logic tier connects to the database and retrieves the requested information. The business logic tier is in charge of forming a secure SQL query based on the user's request. Any parameters to the SQL query should be sanitized to prevent SQL injection attacks.
  4. The business logic tier sends the inventory list back to the client application.
  5. The client displays the inventory list to the user.

请注意,在整个过程中,客户端应用程序永远不会直接连接到数据库。业务逻辑层接收来自经过身份验证的用户的请求,处理客户端对库存列表的请求,然后才执行SQL查询。

Note that in the entire process, the client application never connects directly to the database. The business logic tier receives a request from an authenticated user, processes the client's request for an inventory list, and only then executes a SQL query.

这篇关于如何保护MySQL用户名和密码不被反编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆