在应用程序中隐藏MySQL凭据

4
我需要为一家公司创建一个应用程序,并且他们希望人们登录到应用程序以执行不同的任务。我的初始想法是创建一个MySQL数据库,将凭据硬编码到应用程序中,并使应用程序连接到MySQL数据库。然后,MySQL数据库将拥有一个名为“users”的表,其中存储用户名、密码和权限。应用程序随后将查询服务器并执行身份验证。
这种方法最大的问题在于将MySQL凭据硬编码到应用程序中。如果应用程序落入错误的手中,他们可以在寻找凭据并开始删除表时对MySQL数据库造成很多损害。
因此,我考虑开发一个充当MySQL数据库接口的服务器。例如,客户端应用程序将通过TCP连接到服务器,而服务器将连接到MySQL数据库。这样就永远不会向终端用户公开MySQL凭据。但是,这意味着我必须开发一个服务器应用程序,a) 对于我的客户来说,维护和部署会更加困难(与仅设置MySQL服务器相比),b)可能会引入更多错误,因为我还需要构建一个附加系统(与点a有关的部署错误修正等)。
因此,我想到了一种方法,即不在数据库中使用用户表,并使应用程序直接连接到MySQL服务器以获取硬编码凭据,而是将实际的MySQL用户凭据提供给最终用户,他们将在应用程序中输入这些凭据以连接到MySQL服务器。这意味着如果有人拿到应用程序,他们无法对MySQL数据库造成任何损害,但仍然存在将凭据交给错误人员的风险。
有没有其他解决方案可以让桌面应用程序连接到MySQL数据库?除了我想到的这三种方法之外,是否还有其他解决方案?或者您对我的解决方案有什么想法?

如果这是一个客户端/服务器应用程序,那么一定要考虑在客户端应用程序和MySQL数据库之间实现至少一个薄的服务器层。尽管可能会增加复杂性,但它将显着提高整体解决方案的安全性和可维护性。 - Perception
3个回答

3
正如@Perception所指出的,你最好在MySQL前面实现一个web服务。你不希望来自未知IP地址的未知数量的客户端都访问你的数据库。这样很容易通过占用MySQL连接来进行DOS攻击。而且如果没有中间的web服务,在满足增加客户端需求方面,后端服务的扩展能力将受到非常严重的限制。
该web服务还可以提供各种方式的用户身份验证和授权控制(例如用户/密码组合,基于令牌的访问,OAuth访问等)。

所以只是澄清一下..我应该在MySQL服务器旁边设置一个php服务器,然后从我的应用程序使用HTTP从数据库获取数据? - Brad
是的。Web服务将与数据库通信。客户端应用程序将与Web服务通信。 - Mike Brant

2
我在工作中看到了两种做法:
  1. 每个实体(访问数据库的人、物或业务,根据需要的细粒度而定)都有自己的凭证。这在 MSSQL 和 Rocket Universe 数据库上使用过。这主要用于零售和遗留软件。

  2. 我们自己托管应用程序,并为用户使用单独的身份验证系统。数据库凭据存储在我们托管应用程序的服务器上。客户端对支持数据库一无所知。这通常是 Web 应用程序和 Web 服务。

你可以像我们一样做的一件事是,我们许多应用程序实际上是通过 RESTful 服务进行交流的,该服务以某种方式模拟数据库。应用程序本身无法访问数据库。我建议阅读维基百科关于 RESTful 服务的文章以获取更多信息。我们使用 Nonce 编码 HMAC 请求进行身份验证,每个用户都有自己的密钥与其凭据相关联。

将数据库包装成 Web 服务可以带来一些潜在的优势:

  • 如果您决定更改数据库结构但保留相同信息,则可能根本不需要更新客户端应用程序,只需更新服务即可。
  • 凭据永远不会离开服务器,只要没有人获得访问您的服务器,您的凭据就会保持安全。总体上安全性得到提高。
  • 如果您的服务足够聪明,甚至可以将通常在客户端完成的大部分内部逻辑转移到服务器上,使更新和错误修复对客户端几乎无缝。

我看到的缺点是:

  • 这是需要维护的另一件事。
  • 您的应用程序容易遭受拒绝服务攻击,但由于它是数据库,这是一个可能的问题。
  • 如果服务器崩溃,所有客户端应用程序都会崩溃,但同样仍然是问题。

RESTful 架构:http://en.wikipedia.org/wiki/Representational_state_transfer

HMAC:http://en.wikipedia.org/wiki/Hash-based_message_authentication_code

我们的 HMAC 系统工作方式如下:

  • 用户使用用户名和密码登录其本地应用程序。
  • 本地应用程序与我们的身份验证服务通信,并获取该用户名和密码的“会话密钥”和共享密钥。
  • 使用会话密钥(在短时间内过期),应用程序创建API密钥(长时间有效)并将其存储到计算机上。如果需要每次用户都要登录,则可以使用会话密钥代替API密钥。我们主要是为了某些程序的方便而这样做的。如果计算机不安全,则仅使用会话密钥,不在本地计算机上存储API密钥。每次用户登录时,他们都会获得一个新的会话密钥。
  • 每个对数据库服务的请求都伴随着使用API密钥从授权服务获取的HMAC签名nonce。获取nonce后,应用程序使用共享密钥对其进行签名。由于网络服务(用户可能不知道)验证请求,因此这些签名的请求只能使用一次。通过查看使用特定API /会话密钥的共享密钥将nonce与相同的摘要哈希结果的方式来验证服务器端已经验证了签名的nonce,将该nonce标记为过期并授予请求。

如果未使用HTTPS,则上述内容容易受到中间人攻击,因此人们通常会根据nonce和请求的URL创建消息,并附加时间戳以及在该信息上计算HMAC。然后,服务器会根据URL重新创建消息,检查时间戳是否在某些范围内(+/- 4分钟或其他值),然后基于该信息授权用户。

为了进一步细化操作,我们还具有角色系统,该系统检查Session/API密钥的所有者是否被授予请求他们正在请求的东西的权限。如果他们具有适当的角色,则授予请求。

摘要:凭据是按用户分组的,最终用户不知道数据库,网络服务将数据库包装成RESTful API,并使用基于角色的系统使权限变得更加精细。

这只是一个建议,我不是说这是做此操作的最佳或唯一方式。这只是我们在工作中采用的方法。


0

让我们来看看处理数据库的两种方式:

  • 客户端直接连接数据库并操作数据库
  • 服务器连接数据库并为客户端提供接口以供使用

考虑您的用例:

验证有效的序列号或存储/读取某个用户的信息

可以按照以下方式设计,以提供安全性。(我不是这方面的专家)

  • 客户端直接连接数据库,并操作数据库
    • 您不必使用管理员访问数据库,而是为客户端创建一个用户,并将限制用户的访问权限仅限于查看(某些数据)。您可以通过更改此用户的权限来强制执行数据库的安全策略。
    • 您可以咨询MySQL :: MySQL 5.1 参考手册 :: 6 安全性以获取更多信息。
      • 6.2 MySQL 访问权限系统
      • 6.3 MySQL 用户帐户管理
  • 服务器连接到数据库并提供客户端使用的接口
    • 您可以使用 HTTP 并提供接口给客户端使用。只有后端连接到数据库。
    • 类似于 RESTful API,有许多易于使用的框架提供身份验证和授权。

我认为在您的情况下让客户端直接访问数据库不是一个好主意。因此,如果可能的话,第二个选项更好。

还要注意,基于密码的身份验证并不理想。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接