【问题标题】:PHP Two Way Encryption With Checksum带校验和的 PHP 双向加密
【发布时间】:2017-06-02 07:54:55
【问题描述】:

我正在尝试使用 URL 参数(对于内部 SSO 服务器)将 JSON 字符串从一个 Web 应用程序传递到另一个。

我需要做的是能够使用预共享密钥加密 JSON 字符串(这是一个用户负载对象),将用户转发到服务提供商应用程序,并将负载作为 URL 参数附加,然后打开服务提供商应用程序将负载解密回 JSON 字符串以获取所需信息。

现在这部分不是什么大问题,这要归功于 PHP 的所有内置加密功能,但下一部分是困难。我需要在加密字符串中嵌入一个校验和,可以在解密时对其进行检查,这样如果它在传输过程中被修改,那么我可以引发异常。

这样做的目的是确保用户负载在传输过程中没有被意外或故意修改。

【问题讨论】:

  • @miken32 - 我先看了那篇文章,但它并没有解决我特别想要实现的目标。您发布的主题专门涉及加密密码以及这不是一件好事,而是应该对它们进行哈希处理。我的用例要求使用带有验证签名的可逆加密来验证传输过程中没有任何变化,并使其在 PHP 中工作。
  • 不能只靠https吗?

标签: php encryption checksum


【解决方案1】:

您希望提供的不仅仅是“校验和”(通常定义为“任何一方都可以计算”);您想提供身份验证标签或消息身份验证代码 (MAC)。你有几个选择:

  1. 使用"authenticated encryption" (AE)"authenticated encryption with associated data" (AEAD) 密码来执行此操作。 AE(AD) 密码在密文上提供一个“身份验证标签”,可以是单次传递,也可以是对加密密文的重复处理。示例(可能在您使用的任何 PHP 密码库中都可用)是 GCMEAXCCM推荐,因为如果没有验证认证标签,解密操作将失败,并且只需要一个共享密钥(密钥)。
  2. 您可以使用密码原语自行构建系统。这不太理想,因为您负责更多独立的部分,您需要管理更多密钥(如果您可以访问OMAC implementation,则可以使用相同的密钥),并且您的个人构造未经第三方审查(又名互联网的集体工作)。如果您遵循此路径,则需要牢记一些关键细节:
    • 使用强 hash-based message authentication code (HMAC),例如 HMAC/SHA-256、-384 或 -512。不要使用 SHA-1 或 MD5,因为它们很容易被暴力破解。
    • 在解密密文之前验证 HMAC。 任何失败的 HMAC 都意味着应该丢弃整个密文。您可以将此(在生成端)记住为 Encrypt Then MAC,如果您搜索它,您会发现不遵循此建议是许多加密漏洞和实施漏洞的根源。
    • 使用 常数时间 算法验证 HMAC(即不使用短路字符串相等比较,Java 中的默认设置)。 PHP 提供了hash_equals 来执行此操作。这是quick explanation of timing attackscode review of a PHP example

对于任何一种选择,您都需要使用 URL 安全的 Base64 对生成的密文和身份验证标签进行编码,以避免数据丢失或损坏。如果您的消息格式没有严格地包含长度,您必须提前预先共享协议(即对于长度为 n 个字节的消息 m -> 16 bytes IV | n-48 bytes cipher text | 32 bytes HMAC)。

最后一点:始终为每条使用密钥加密的消息使用唯一的、不可预测的 IV。许多人忽略了这一点,因为它“很容易使用0x00 * 16”,但是任何像CTR这样用作GCM和CCM基础的流密码操作模式,如果两条消息都用相同的 IV 和密钥。

【讨论】:

  • 根据你所说的@Andy,这似乎正是我正在寻找的东西,但是在 PHP 的文档中的检查表明 OpenSSL 库目前不支持 AEAD。似乎 OpenSSL 本身可能支持它(无论如何都是 GCM 和 CCM),但该功能不能嵌入 PHP 中。如果它可以在我的 php7.0 应用程序中工作,那就完美了。
  • Scott Arciszewski @CiPHPerCoder,我信任 PHP 加密的所有事物,推荐 libsodium-php
  • 这里有关于如何使用它的大量文档:Using Libsodium in PHP Projects
  • 感谢安迪,它运作良好,似乎做了我需要做的事,最后一个问题,因为它使用了一个随机数,我以前没有使用过它们,同样通过随机数是否安全消息作为加密的 JSON 序列。 IE:something.php?e=ciphertext&n=nonce,如果现在将 nonce 获取到其他 Web 应用程序进行解密的最佳方式是什么,因为 nonce 每次都应该不同,所以不能预先-共享。
  • 是的,在消息旁边传递随机数(不受保护)是安全的。我在回答中提到 IV 的任何地方,你都可以用它来代替 nonce。 IV 本质上是 8-13 字节的 nonce 加上一个递增的计数器值(有关其工作原理的图表,请参阅 the Wikipedia entry for CTR)。大多数系统只是在密文前面加上 IV,然后 Base64 对整个内容进行编码,因为 IV 始终是必需的,并且始终为 16 个字节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
  • 2011-04-15
  • 2011-04-23
  • 2016-01-31
  • 1970-01-01
  • 2015-03-20
  • 2011-09-11
相关资源
最近更新 更多