【问题标题】:Hiding MySQL Credentials in Application在应用程序中隐藏 MySQL 凭据
【发布时间】:2013-03-07 12:42:24
【问题描述】:

我需要为一家公司创建一个应用程序,他们希望人们登录该应用程序以获得不同的权限来执行不同的任务。

我最初的想法是创建一个 MySQL 数据库,将凭据硬编码到应用程序中,然后让应用程序连接到 MySQL 数据库。 MySQL 数据库将有一个名为“users”的表,该表将存储用户名、密码和权限。然后应用程序将查询服务器并执行身份验证。

最大的问题是将 MySQL 凭据硬编码到应用程序中。如果应用程序落入坏人之手,如果他们四处寻找凭据并开始删除表,他们可能会对 MySQL 数据库造成很大损害。

所以我想开发一个服务器来充当 MySQL 数据库的接口。例如,客户端应用程序将通过 TCP 连接到服务器,服务器连接到 MySQL 数据库。这样,MySQL 凭据就不会暴露给最终用户。但是,这意味着我必须开发一个服务器应用程序,它 a) 将更难为我的客户维护和部署(而不是仅仅设置 MySQL 服务器)和 b) 有可能引入更多错误,因为我有一个额外的系统我需要做(这与部署错误修复等有关)

所以我在想,与其在数据库中使用用户表并让应用程序使用硬编码凭据直接连接到 MySQL 服务器,不如为最终用户提供实际的 MySQL 用户凭据,他们将在其中输入应用程序连接到 MySQL 服务器。这意味着,如果有人拿到了应用程序,他们不会对 MySQL 数据库造成任何损害,但仍然存在最终用户将其凭据提供给错误人的风险。

让桌面应用程序连接到 MySQL 数据库的最佳方法是什么?除了我想到的 3 种之外,还有其他解决方案吗,或者您对我的解决方案有什么想法吗?

【问题讨论】:

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

标签: c++ mysql security desktop-application


【解决方案1】:

正如@Perception 所说。你最好的选择是在 MySQL 前面实现一个 Web 服务。您不希望来自未知 IP 地址的未知数量的客户端都可以访问您的数据库。

通过捆绑 MySQL 连接来 DOS 攻击你真的很容易。更不用说在没有 Web 服务的情况下扩展后端服务以满足不断增长的客户群的需求的能力会非常严重。

Web 服务还可以让您以多种方式控制用户身份验证和授权(用户/通行证组合、基于令牌的访问、OAuth 访问等)。

【讨论】:

  • 所以只是澄清一下..我应该在 MySQL 服务器旁边设置一个 php 服务器,然后使用我的应用程序中的 HTTP 从数据库中获取数据?
  • 是的。 Web 服务将与数据库通信。客户端应用程序将与 Web 服务通信。
【解决方案2】:

在我工作的地方,我看到了两种做法:

  1. 每个实体(个人、事物或企业(取决于所需的粒度级别)访问数据库)都有自己的凭据。这用于 MSSQL 和 Rocket Universe 数据库。这主要是零售和旧版软件。

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

我们可以做的事情是,我们的许多应用程序实际上通过一个 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 密钥。每次用户登录时,他们都会获得一个新的会话密钥。
  • 对数据库服务的每个请求都附有一个 HMAC 签名的随机数,应用程序根据 API 密钥从授权服务中获取该随机数。获得随机数后,应用程序使用共享密钥对其进行签名。这些签名的请求只能使用一次,因为 Web 服务(用户对此一无所知)对请求进行身份验证。一旦通过查看使用该特定 API/会话密钥的共享密钥对 nonce 进行哈希处理是否会产生相同的摘要,对已签名的 nonce 进行了服务器端身份验证,该 nonce 将被标记为过期并授予请求。

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

为了进一步细化操作,我们还有一个角色系统,用于检查拥有会话/API 密钥的用户是否已获得请求他们所请求内容的权限。如果他们具有适当的角色,则批准请求。

总结:凭据是逐个用户完成的,最终用户不了解数据库,Web 服务将数据库包装在 RESTful API 中,并使用基于角色的系统使权限细化。

这只是一个建议,我不是说这是最好的或唯一的方法。这恰好是我们最终在我工作的地方这样做的方式。

【讨论】:

    【解决方案3】:

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

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

    考虑您的用例:

    有效的有效序列号或存储/读取有关特定用户的信息

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 2013-09-12
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      相关资源
      最近更新 更多