在应用程序中隐藏MySQL凭据

时间:2013-03-19 00:19:13

标签: c++ mysql security desktop-application

我需要为公司创建一个应用程序,他们希望让人们登录到该应用程序,以便具有执行不同任务的不同权限。

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

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

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

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

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

3 个答案:

答案 0 :(得分:3)

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

通过捆绑MySQL连接,DOS攻击你真的很容易。更不用说你会非常严格地限制你扩展后端服务的能力,以满足增加客户群的需求,而不需要在它们之间提供Web服务。

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

答案 1 :(得分:2)

我工作的地方有两种我见过的做法:

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

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

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

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

    为了进一步细化操作,我们还有一个角色系统,它检查拥有Session / API Key的用户是否已获得请求他们请求的东西的权限。如果他们具有适当的角色,则授予该请求。

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

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

答案 2 :(得分:0)

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

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

考虑您的使用案例:

  

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

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

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

我认为让客户端直接访问您的数据库是个好主意。因此,如果可能,第二种选择更好。

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