PHP中的RFC 2246 PRF函数

时间:2013-04-12 13:58:33

标签: php hash cryptography kdf

我一直在寻找RFC 2246中PRF功能的实现。我发​​现了三个。一个here,一个来自openSSL库,另一个来自wpa_supplicant。他们都返回不同的结果。所以我的第一个问题是:是否有样本PRF输入和样本PRF输出?

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

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

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

秘密,标签,种子。

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

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

1 个答案:

答案 0 :(得分:0)

我和他一起战斗了两天,但我最终成功了。这是我的PHP psha1函数,它基于a reply to "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);
}
相关问题