2

我一直在寻找 RFC 2246 中 PRF 函数的实现。我找到了三个。一个在这里,一个来自 openSSL 库,一个来自 wpa_supplicant。它们都返回不同的结果。所以我的第一个问题是:某处是否有样本 PRF 输入和样本 PRF 输出?

该功能是从 PHP 连接到 .NET Web 服务(受 WS-Security 保护)的一部分。

到目前为止我发现的是这个。我的客户首先使用用户名/密码和随机数发送一个令牌请求——这是一个 RST。服务器在其 RSTR 中以另一个 nonce 和一个安全令牌进行响应。我的客户的下一个请求应该带有一个签名,其密钥来自两个随机数和一个“主密钥”。该派生密钥是根据 RFC 2246 计算的。这就是为什么我需要一个可靠的实现。

即使我有一个可靠的实现,在 WS-Security 的上下文中,该函数的参数是什么?PRF 函数应采用三个参数,即:

秘密,标签,种子。

我在这里读到,微软使用的标签是“WS-SecureConversationWS-SecureConversation”,但那篇文章是在 2006 年写的……现在,秘密是什么?是原密码吗?安全令牌?这些的组合?最后,种子是什么?我有两个随机数——我是连接它们,还是它们,异或?

我被严重卡住了。非常感谢任何帮助。

4

1 回答 1

0

我为此奋斗了两天,但最终还是成功了。这是我的 PHP psha1 函数,它基于在对 "signing SOAP message request via ADFS" 的回复中找到的 C# 方法。将您的 RST 和 RSTR、base64_decode 分别作为 $clientSecret 和 $serverSecret 传递给此函数。令牌响应应该带有一个 KeySize 元素,如果它不等于 256,您可以将其作为 $sizeBits 传递。

function psha1($clientSecret, $serverSecret, $sizeBits = 256)
{
    $sizeBytes = $sizeBits / 8;

    $hmacKey = $clientSecret;
    $hashSize = 160; // HMAC_SHA1 length is always 160
    $bufferSize = $hashSize / 8 + strlen($serverSecret);
    $i = 0;

    $b1 = $serverSecret;
    $b2 = "";
    $temp = null;
    $psha = array();

    while ($i < $sizeBytes) {
        $b1 = hash_hmac('SHA1', $b1, $hmacKey, true);
        $b2 = $b1 . $serverSecret;
        $temp = hash_hmac('SHA1', $b2, $hmacKey, true);

        for ($j = 0; $j < strlen($temp); $j++) {
            if ($i < $sizeBytes) {
                $psha[$i] = $temp[$j];
                $i++;
            } else {
                break;
            }
        }
    }

    return implode("", $psha);
}
于 2013-11-11T18:40:31.407 回答