同一系统上的两个应用程序之间的安全通信

信息安全 tls 协议 tcp 建筑学
2021-08-13 02:17:22

我正在编写一个软件,它分为两个独立的独立部分。一个是处理所有逻辑的类似服务的应用程序,另一个是仅用作前端并旨在供最终用户使用的 GUI 应用程序。该服务将侦听端口并接受来自客户端 (GUI) 应用程序的请求。

由于服务和 GUI 应用程序之间交换了一些敏感信息,因此在传输之前需要对其进行加密。保护数据的一种方法是使用基于密钥的加密,但密钥需要存储在磁盘上的某个位置,甚至存储在应用程序的源代码中,但宁愿避免使用密钥。

如何在不使用基于密钥的加密算法的情况下处理服务和 GUI 应用程序之间的安全连接?

3个回答

这些是计算机安全的黄金法则:“不可能对具有系统管理员权限的合格用户隐藏任何内容”和“任何可以物理访问设备的合格用户始终可以将自己提升为系统管理员”。

您不能对拥有机器物理控制权的人隐藏任何信息。如果您试图隐藏的秘密非常重要,那么您永远不应该将数据传输到机器并在您控制的其他地方进行处理。

您的程序正在用户的机器上运行。您无法保护您的数据免受用户的侵害。考虑到这一点,这是否意味着我们注定要失败?不必要。操作系统为程序提供了丰富的机制与另一个程序私下通信,不允许另一个无特权的应用程序拦截它。因此,虽然您无法保护用户自己的任何数据,但您可以保护您的数据免受其他非特权程序的侵害。在非特权程序之间提供安全边界是操作系统的主要工作之一。

其中最简单的是匿名管道。管道允许在程序之间传输单向数据流。匿名管道可用于 Windows、Linux、OSX 和所有类 Unix 系统。匿名管道通常被认为是一对称为 stdin 和 stdout 的管道,它允许父进程向其子​​进程发送和接收数据流。匿名管道只能在具有父子关系的进程之间使用。还有一个命名管道,但它们在 Windows 和 Linux/类 Unix 系统中的行为不同,我们稍后再讨论。

另一种常用的 IPC 是套接字。套接字就像一个双向管道。有许多不同的套接字,但它们的工作方式相似。最广为人知的是 TCP 套接字。TCP 套接字主要用于机器之间的网络,但您也可以创建只能在同一台机器内使用的环回 TCP 套接字。环回套接字提供隐私(只有连接的程序和侦听的程序才能读取通过套接字的数据),但是它并没有真正提供机制来限制谁可以成为套接字的另一端。

Unix 中用于同一台机器中进程之间通信的另一种套接字类型是 Unix 域套接字。Unix 域套接字作为文件系统中的“特殊文件”向程序公开,Unix 文件系统权限用于控制对套接字的访问。没有权限访问套接字文件的程序无法连接域套接字。在类 Unix 系统中,这意味着您的服务和 GUI 应该作为仅为您的程序保留的相同用户和/或组运行,并且您适当地设置了套接字文件权限。

让我们回到命名管道。在 Linux/类 Unix 系统中,命名管道与标准输入/标准输出非常相似,因为它们是单向的。然而,在 Windows 中,命名管道实际上是双向的,几乎等同于 Windows 中的 Unix 域套接字。像 Windows 中的许多东西一样,命名管道使用 ACL 保护。

有了 iOS,事情变得有点棘手。未越狱的 iOS 只允许非常有限的一组进程间通信,而且都不会给你一个套接字。但是如果我们放宽定义,在 iOS 应用程序中,服务程序和 GUI 程序可能实际上是同一个应用程序,因此您可以简单地在应用程序的不同组件之间直接创建一个流。这也是安全的,因为流只能在应用程序内访问。

Android 为 IPC 提供了更多选项,包括创建域套接字的能力。API 有所不同,但它们在概念上与常规 Linux 相似。或者,您可以采用与 iOS 中相同的方法,将您的服务和 GUI 打包在同一个应用程序中,并且只使用进程内流。

我假设您是机器上唯一的 root/管理员。

您可以使用以下两个选项之一:

  1. 根本不允许该机器上的其他用户
  2. 让进程以特殊用户身份运行,并使用仅对该用户可访问(读+写)的通信机制(命名管道、unix 域套接字等)

这两个选项中的任何一个都将使您无需在传输过程中加密您的数据。

注意:如果机器上有另一个(足够熟练的)管理员,您根本无法隐藏任何内容(包括加密密钥)。

基本上,安全性通常由密钥而不是算法来承担。所以你在这里做傻事。正如 Kerckhoff 原则所说:“密码系统应该是安全的,即使系统的所有内容(除了密钥之外)都是公共知识。”或者如香农重新表述的那样:“敌人知道系统”。所以你不能真正拥有一个不使用某种形式的密钥并且真正安全的密码系统。

既然你提到 在您的标签列表中,让我提醒您原则上这是如何工作的。

SSL/TLS (https) 的想法是协商一个对称加密密钥,用于客户端和服务器之间的通信会话。客户端连接到服务器并请求其公钥(非对称加密)。密钥作为证书的一部分提供,可以使用证书的认证链进行验证。使用该公钥和证书的正确验证,客户端知道它在与谁交谈。所以他可以安全地传递信息。

然后,客户端可以使用公钥协商一个对称密钥,以便在此会话中相互交谈。无法为通信之外的任何人派生密钥(如有必要,请参阅更详细的说明https://security.stackexchange.com/a/20833/1574

通过使用 TLS,可以确保两个合作伙伴之间的机密性,并且客户端也可以使用证书链对服务器进行身份验证。如果需要对客户端进行身份验证,TLS 也支持客户端证书。