14

我想让一个守护进程类型的进程(即无用户交互)访问共享密钥,以便它可以访问共享的加密数据文件。访问相同加密数据的用户应用程序将共享密钥存储在用户的OS密钥链中(例如OS X keychain或Gnome Keyring等)。操作系统密钥链反过来用用户的登录(或其他特定于用户的)密码保护密钥。

这里的加密用于在服务器和客户端之间传输公共网络时保护数据。所讨论的数据是来自科学实验的原始数据。大多数都是无价值的(即不太可能吸引攻击者来推测性地破坏加密并浏览数据),但其中一些可能非常有价值,用户希望在选择公开共享其详细信息之前将其保密(即保护其免受网络上的临时观察者的攻击)。如果没有科学分析,很难确定数据的价值,因此在用户传输未加密的线路时观察用户的活动(包括查询)将为观察者提供有关数据价值的一些线索。

守护进程是系统的查询服务器。它从共享数据中读取数据,处理查询,并将结果集的标识符返回给客户端,然后客户端从共享存储中提取已标识的数据。

我们允许将加密数据同步到用户的本地工作站/笔记本电脑,所以磁盘上的数据加密对决心坚定的攻击者来说至多是一件麻烦事。我们允许用户在本地运行查询服务器(仍然由init.d/launchd启动),所以我想尽我所能保护与守护进程一起存储的密钥。主要风险是,确定的恶意用户能够从其系统上的守护程序中发现密钥。暴露该密钥需要我们更改密钥,更新所有用户的密钥,然后重新加密数据库。

存储守护进程的共享密钥的最佳方法是什么?我可以将密钥放在磁盘上并在磁盘上加密文件,但守护进程必须有密钥才能解密该文件。这似乎等同于只拥有原始加密数据的共享密钥。我天真的做法是将密钥存储在应用程序的二进制文件中,但我无法想象这是最好的选择。有什么建议吗?

5
  • 哪些账户必须读/写数据?守护进程只是读取用户所写的内容,反之亦然,还是双向读取?
    – 用户185
    评论 2011年1月18日18:22
  • 你想让守护进程在意外重启后继续存在吗?如果是这样,这是一个相当棘手的问题。如果没有,管理员可以在启动时为其提供密钥吗? 评论 2011年1月18日18:46
  • @Graham守护进程只需要读取数据,但加密是对称AES(我们无法控制)。 评论 2011年1月18日18:59
  • @nealmcb守护进程是由Linux上的init.d脚本或OS X上的launchd作业启动的。我们在一个IT预算非常低的环境(学术界)中运行,所以我想避免管理员参与。显然,将密钥放在init.d或launchd脚本/文件中可能比放在二进制文件中更糟糕,但只是稍微差一点。 评论 2011年1月18日19:00
  • 你想实现什么?你想保护什么?来自谁?你的威胁模型是什么?这个问题没有很好的定义。 评论 2011年1月19日7:16

5个答案5

重置为默认值
12

这很快就变成了一个“海龟一直向下”的问题。你只需要决定在什么时候停止加密,然后使用另一种方法。我认为目标应该是阻止临时用户,而不是坚定的黑客,轻松获取受保护的数据。

我在一个需要存储DB密码和SSL证书密码的web应用程序中使用了类似的方法。我最终做的是使用不同的主密码。主密码存储为应用程序启动脚本设置的环境变量。由于主密码仅在启动脚本中设置,因此很容易让单个用户访问该脚本,并能够使用标准的UNIX文件权限运行该脚本。

我的想法是,要想访问这个脚本,您必须已经是root用户,在这一点上,这并不重要。如果你不能信任root用户(或者服务器被黑客攻击),你可能还有其他问题。

此外,这里通过模糊性有一点安全性,因为所有关于此工作原理的细节都没有很好地记录在案。您必须回溯启动脚本的工作方式,然后找出使用的算法、salt+plantext的格式等。如果您想获得DB密码并达到这一步,我想您可能已经直接进入了DB服务器。

7

像往常一样,最好从问自己几个问题开始:你的威胁模型是什么?你想保护什么?你想保护它不受谁的伤害?你为什么首先使用加密?这些问题都不清楚。(加密不是神奇的仙尘。)如果没有这些问题的答案,我们无法给你一个解决方案:正确的解决方案取决于你试图实现的目标。

一般来说,这个问题没有很好的解决方案。如果你想在不需要用户参与的情况下启动系统,那么私钥将在磁盘上的某个地方以明文形式存在(或者以明文等效形式存在)。正如其他人所建议的那样,你会很快击中“乌龟”。

您可以采取的一个步骤是确保私钥受到文件系统访问控制的保护:例如,根用户可以读取,但普通用户不能读取。

脚注:有一些复杂的方法,但它们可能不适合您的低成本环境。(1) 一种更安全的方法是将私钥存储在连接到服务器的硬件安全模块中。如果服务器受到威胁,软件无法窃取私钥(但它仍然可以指示硬件安全模块对任意消息进行签名/解密)。(2) 一种更复杂的方法是使用TPM,并将私钥锁定到特定的软件块。不幸的是,当前的操作系统并没有对此提供良好的支持,因此作为一名系统管理员将面临很大的挑战:这将需要大量的开发人员支持。

2
  • 我不是appsec专家(显然),但我尝试在我编辑的问题中指定您的问题的答案。 评论 2011年1月19日19:16
  • @巴里,明白了,谢谢。是的,我认为(考虑到成本限制)您能做的最好的事情是将密钥存储在文件系统中,并确保它只能由root(或运行守护进程的用户ID)读取。 评论 2011年1月27日6:33
1

守护进程的帐户是否有可用的密钥链?

  • 2
    可能不是-默认情况下,root帐户没有密钥链,bin、daemon等也没有。系统密钥链是防篡改的。守护进程可以创造为其帐户创建一个密钥链,但现在您在哪里存储密码短语?
    – 用户185
    评论 2011年1月18日18:34
  • 啊,说得好。
    – 史蒂夫
    评论 2011年1月18日18:56
  • yfuhs正如Graham所说,我们可以创建一个密钥链,但守护进程需要知道该密钥链的密码。 评论 2011年1月18日19:01
1

为了完整起见,我们选择的解决方案是@SteveSyfuhs和@AngerClown的答案的组合。在OS X上,我们正在使用System keychain(/库/钥匙链/系统.钥匙链). 在Linux上,我们将加密密钥存储在一个权限位为400(即仅所有者只读)的文件中,该文件归root所有。

1
  • 1
    对我来说,这听起来很明智,而且是任何人都能合理做到的(考虑到你的限制)。 评论 2011年1月27日6:34
1

巴里,我喜欢你的解决方案,我有一个想法,可以更进一步。如何保持用于创建新机器的机器映像在密钥文件中自动设置为使用400,然后在引导时以root身份启动服务器软件,将密钥读入内存,删除密钥,然后将运行服务器软件的用户切换为非root帐户。

你必须登录来回答这个问题。

不是你想要的答案吗?浏览标记的其他问题.