java – 我如何保护MySQL用户名和密码免受反编译?

Java .class文件可以很容易地反编译。如果我必须使用代码中的登录数据,如何保护我的数据库?
不要将密码硬编码到代码中。这是最近在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.

您应该将配置信息(包括密码)存储在应用程序启动时读取的单独文件中。这是唯一真正的方法,以防止密码泄漏作为反编译的结果(从来不编译成二进制开始)。

有关这一常见错误的更多信息,您可以阅读CWE-259 article.本文包含更全面的定义,示例和大量有关该问题的其他信息。

在Java中,最简单的方法之一是使用Preferences类。它被设计为存储各种程序设置,其中一些可以包括用户名和密码。

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
}

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

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

更重要的注释:在这个答案和其他人的评论中有很多讨论,关于这种情况的正确架构。原始问题并没有真正提到应用程序正在使用的上下文,所以我将谈论我可以想到的两种情况。第一种是其中使用程序的人已经知道(并且被授权知道)数据库凭证的情况。第二种情况是,您,开发人员,试图保持数据库凭据秘密的人使用该程序。

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

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

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

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

正确的情况:使用多层体系结构

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

每个用户都有自己的用户名和密码,可以本地存储在首选项文件中,没有任何安全风险。这称为three-tier architecture(这些层是您的数据库服务器,业务逻辑服务器和客户端应用程序)。它更复杂,但它真的是最安全的方式做这种事情。

操作的基本顺序是:

>客户端使用用户的个人用户名/密码验证业务逻辑层。用户名和密码是用户已知的,并且不以任何方式与数据库登录凭据相关。
>如果认证成功,客户端向业务逻辑层请求从数据库中获取一些信息。例如,产品的库存。请注意,客户端的请求不是SQL查询;它是一个远程过程调用,如getInventoryList。
>业务逻辑层连接到数据库并检索所请求的信息。业务逻辑层负责根据用户的请求形成安全的SQL查询。应该对SQL查询的任何参数进行清理,以防止SQL注入攻击。
>业务逻辑层将清单列表发送回客户端应用程序。
>客户端向用户显示清单列表。

请注意,在整个过程中,客户端应用程序从不直接连接到数据库。业务逻辑层从认证用户接收请求,处理客户端对库存列表的请求,然后仅执行SQL查询。

http://stackoverflow.com/questions/442862/how-can-i-protect-mysql-username-and-password-from-decompiling

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – 我如何保护MySQL用户名和密码免受反编译?