带校验和的PHP双向加密

时间:2017-01-18 03:35:07

标签: php encryption checksum

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

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

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

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

1 个答案:

答案 0 :(得分:2)

您希望提供超过"校验和" (通常定义为"可由任何一方计算");您想提供身份验证标记或消息身份验证代码(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都意味着应丢弃整个密文。你可以记住这个(在生成方面)加密然后MAC ,如果你搜索它,你会发现不遵循这个建议是许多加密漏洞和实现漏洞的根源。
    • 使用恒定时间算法验证HMAC(即不使用短路字符串相等性比较,Java中的默认值)。 PHP提供hash_equals来执行此操作。这是quick explanation of timing attackscode review of a PHP example
  3. 对于任何一种选择,您都希望使用URL安全的Base64对生成的密文和身份验证标记进行编码,以避免数据丢失或损坏。如果您的消息格式没有严格按照包含长度进行结构化,则您必须提前预先共享协议(即,对于长度 n 字节的消息 m - > 16 bytes IV | n-48 bytes cipher text | 32 bytes HMAC)。

    最后一点:始终对每个使用密钥加密的邮件使用唯一的,不可预测的IV。很多人都对此有所了解,因为它很容易使用0x00 * 16",但任何流密码操作模式如CTR用作GCM的基础如果两条消息使用相同的IV和密钥加密,CCM将失去基本安全性。