【问题标题】:PHP - Encryption and signature creation for web servicePHP - Web 服务的加密和签名创建
【发布时间】:2012-11-01 03:00:51
【问题描述】:

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

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

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

我尝试过的一切都只是从网络服务中抛出一个错误。

对于“秘钥”,简述为:

  1. ASCII 编码纯文本密码
  2. 使用 MD5 散列编码密码
  3. 获取 MD5 哈希字节并执行按位运算'& 127'
  4. 转换为base64字符串

我不清楚第 3 点 - 其余部分非常简单;我在这里错过了什么?

然后生成认证签名的简要说明是:

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

再一次,我在上面看不到任何问题 - 只是第 3 点让我感到困惑。

任何指针?

【问题讨论】:

  • 和这个有关系吗...Bitwise Operations ?
  • 我已经看过了,但这对我来说意义不大 - 尤其是在相当奇怪的简介中(获取 MD5 哈希字节并执行按位运算'& 127')

标签: php encryption cryptography md5 cryptographic-hash-function


【解决方案1】:

我不清楚第 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;
}

演示here.

为什么会有人这样做?

具体来说:

获取 MD5 哈希字节并执行按位运算'& 127'

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多