如何在两个远程设备之间安全地共享密钥?

信息安全 AES 客户端 秘密分享
2021-09-09 16:24:27

假设我有一个服务器/客户端拓扑,目前我面临的问题是我想在客户端生成一些密钥并以某种方式让远程服务器安全地获取它。

我在这两个部分都使用 AES,所以基本上我需要的是生成一个随机IV和一个随机密钥,但是如何与服务器共享它以便它可以随后解密消息?

服务器端是 Apache/PHP Web 服务器,因此请求将通过 发送POST,我肯定会使用SSL证书,但我不确定这是否足以安全地将数据发送到另一端。

我将不胜感激任何方法/想法。

- - 编辑 - -

这实际上是一个 Android 操作系统应用程序。Socket我没有对服务器使用 direct ,而是使用HTTP POST从客户端到服务器的请求,并Google Cloud Messages以相反的方式模拟多播行为,因为服务器将向订阅的用户发送新事件。

但是这些消息只会发送给注册用户,所以在发送之前我需要注册用户,从而在服务器和客户端之间共享密钥,这就是问题的动机。

4个回答

您正在寻找的是在计算机世界中也称为 SSL 的公钥/私钥对。

您提到的 SSL 证书具有足够的安全性,因为要找出发送的内容,您需要证书的私钥,而如果不侵入服务器,您将无法获得它。

如果您不想使用 SSL,另一种选择是在客户端/服务器中使用硬编码的公钥/私钥对,其作用类似于 SSL,但没有签名证书。

如果正确理解了这个问题,那么这里真正要问的是如何进行密钥交换

以与安全产品讨论的相同方式实现了这一点,以下通用方法独立于底层传输协议工作(并且进一步不对其底层安全性做出任何假设):

  1. 客户端使用一些(假定的)良好的 IV 和适用于 AES256(或更好)加密的强伪随机算法生成(随机)事务密钥。

  2. 客户端使用与步骤 (1) 中相同的过程生成(新的随机)对称响应密钥。

  3. 客户端使用来自 (1) 的事务密钥加密响应密钥 (2) ... 使用 AES256 或任何首选算法。

  4. 通过PKI,客户端使用服务器公钥对服务器(接收方)的交易密钥 (1) 进行非对称加密。这将确保只有服务器可以读取事务密钥 (1)。

  5. 生成识别客户端(发送方)的有效负载,与服务器(接收方)端的公钥相关联。在此有效负载中将是(PKI 加密)事务密钥(1)和(AES 加密)响应密钥(2)。还有更多内容,例如散列内容以确保不可否认性等 - 但让我们专注于密钥交换......

  6. 客户端将有效负载发送到服务器。建议通过 TLS 等来完成,但这并不是绝对必要的,因为加密足以保护密钥。但是,确保客户端在没有窃听的情况下将有效负载发送到 [正确] 服务器(接收方)可以提高密钥交换的安全性。

  7. 通过 PKI(使用服务器私钥)解密负载的第一部分:交易密钥。

  8. 使用事务密钥,使用 AES256 解密响应密钥(必须与用于响应密钥加密的算法和 IV 相同 - 应该是有效负载的一部分)。

  9. 此时,客户端等待来自服务器的响应。

  10. 服务器使用客户端知道(他生成的)此事务的响应密钥,然后可以简单地使用 AES256(某种对称算法)加密绑定到客户端的任何内容。

  11. 客户端使用对称算法和响应密钥来解密服务器响应。

如果 PKI 密钥不被泄露,使用良好的盐、IV 等……这个过程非常可靠(世界各地的安全组织都在使用)。

请注意,任何密码术最终都可能被破解。为每个请求/响应对使用这个基于事务的过程和新的(密钥的随机性很重要)(大)伪随机密钥,很难破坏对话。

使用这种方法,即使一个交易密钥被泄露,它也极大地限制了暴露,因为一次只能获得对单个交易的访问权限。

安全套接字层 (SSL)似乎是您正在寻找的答案。这是维基百科页面的引述:

他们使用 X.509 证书和非对称加密技术来确保与他们通信的对方,并交换对称密钥该会话密钥随后用于加密各方之间流动的数据。这允许数据/消息的机密性和消息完整性的消息验证代码以及作为副产品的消息验证。

此外,您可能只想看看RSADiffie-Hellman算法,它们可用于客户端/服务器模型以安全地交换密钥。但是,它们附带多种类型的攻击;中间人就是其中之一,入侵者可能只是介入并偷走钥匙。另一种可能的攻击是暴力破解,入侵者可能会猜到您尝试传输的密钥。

如果您想使用这些算法安全地交换密钥,请确保使用MD-5SHA-X算法对它们进行哈希处理。如果有空间,您甚至可以使用DES /Double DES/ Triple DESAES-128/192/256加密算法对它们进行加密。

通读此:

在客户端和服务器可以开始交换受 TLS 保护的信息之前,它们必须安全地交换或同意加密数据时使用的加密密钥和密码。用于密钥交换/协议的方法包括:使用 RSA 生成的公钥和私钥(在 TLS 握手协议中表示为 TLS_RSA)、Diffie-Hellman(在 TLS 握手协议中表示为 TLS_DH)、临时 Diffie-Hellman(在握手协议)、椭圆曲线 Diffie-Hellman(表示为 TLS_ECDH)、短暂椭圆曲线 Diffie-Hellman(TLS_ECDHE)、匿名 Diffie-Hellman(TLS_DH_anon)和 PSK(TLS_PSK)。TLS_DH_anon 密钥协商方法不对服务器或用户进行身份验证,因此很少使用。只有 TLS_DHE 和 TLS_ECDHE 提供前向保密。交换/协议期间使用的公钥证书在交换期间使用的公共/私人加密密钥的大小以及所提供的安全性的稳健性方面也有所不同。2013 年 7 月,Google 宣布将不再使用 1024 位公钥,而是改用 2048 位密钥,以提高其提供给用户的 TLS 加密的安全性。

两个答案都已识别 SSL/TLS,但请考虑将客户端身份验证添加到组合中。这将保证服务器只接受经过身份验证/已知客户端的连接。这样做的缺点是:

  • a) 必须为每个客户端颁发其自己的客户端身份验证证书(尽管不一定来自与服务器相同的 CA)。
  • b) 每个客户端必须存储匹配的私钥。这可能在软件中(尽管它可以存储在智能卡或 PKI USB 令牌上)。
  • c) 每个客户端都必须向服务器注册,尽管这可能基于服务器实现而有所不同。一些服务器可能允许基于已知根 CA 证书的信任。一些服务器可能会接受基于白名单方法的证书。有些可能是两者或替代方案的混合。

服务器应该能够配置为仅接受客户端身份验证的连接。在某些 Web 服务器中,此设置可以应用于服务器上的各个资源。

查看 Wikipedia 页面以了解客户端经过身份验证的 TLS 握手的详细信息:

TLS 客户端身份验证