2

我需要使用 PHP 创建一个“密钥”才能使用 Web 服务,但这对我来说毫无意义。

Web 服务已被证明可以与 C# 应用程序一起使用,但我需要通过 PHP 访问它。

为了使用该服务,我需要一个“密钥”,然后是基于该密钥的身份验证签名。

我尝试过的所有操作都会从 Web 服务中引发错误。

对于“秘钥”,简要说明为:

  1. ASCII 编码纯文本密码
  2. 使用 MD5 对编码密码进行哈希处理
  3. 获取 MD5 哈希字节并执行按位操作 '& 127'</li>
  4. 转换为base64字符串

我不清楚第 3 点——其余的都很直截了当;我在这里想念什么?

然后生成身份验证签名的简要说明是:

  1. 密钥的 UTF-8 编码(秘密访问密钥是第 4 步的结果)
  2. 日期的 UTF-8 编码
  3. HMAC-SHA1 (UTF-8-Encoding-Of (Secret access key, RequestDate))
  4. Base 64 字符串

同样,我在上面看不到任何问题 - 这只是第 3 点让我失望。

任何指针?

4

1 回答 1

3

我不清楚第 3 点——其余的都很直截了当;我在这里想念什么?

您描述的签名算法远非安全。最好使用 Ed25519(通过sodium_crypto_sign_detached()sodium_crypto_sign_verify_detached())而不是这种 MD5 和 SHA1 废话。

话虽如此,他们可能期待这样的事情:

function insecureMd5Kdf($message, $raw = false)
{
    $bytes = md5($message, true);
    $output = '';
    for ($i = 0; $i < 16; ++$i) {
        $int = ord($bytes[$i]) & 127;
        $output .= pack('C', $int);
    }
    if (!$raw) {
        return bin2hex($output);
    }
    return $output;
}

演示在这里

为什么会有人这样做?

具体来说:

获取 MD5 哈希字节并执行按位操作 '& 127'</p>

在 Java 中,字节的范围可以从-128127. 使用& 127运算符清除较高位,将可能值的范围缩小到 [0, 127]。

我怀疑答案是“惰性编程”。也就是说,有人想要快速解决 Java 和 PHP 之间的差异并清除 MD5 哈希的每个字节的高位,从而使他们不必将 [128, 255] 范围内的数字转换为 [-128, -1]。

如果此 Web 服务仍然存在,您应该向他们询问最新的安全审计结果。

于 2018-10-02T13:36:18.917 回答