5

尝试向服务器发送肥皂请求 (soapCall) 时出现错误。

Fatal error: Uncaught SoapFault exception: [ns1:InvalidSecurity] An error was discovered processing the <wsse:Security> header

我需要发送 ws-security 标头

<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

<wsse:Username>userID</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passwd</wsse:Password>

<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">ZTQ3YmJjZmM1ZTU5ODg3YQ==</wsse:Nonce>

<wsu:Created>2013-07-05T19:55:36.458Z</wsu:Created>

</wsse:UsernameToken>
</wsse:Security>

经过大量研究,我认为我得到的问题是随机数不符合要求。当我制作肥皂头时,它看起来就像我得到的例子。唯一未知的元素是计算这个随机数......

从我得到的示例随机数中,它是一组 24 个数字 + 字母 + 特殊字符

像这样的东西

ZTQ3YmJjZmM1ZTU5ODg3YQ==

但是,我不太确定你如何从 php 计算 wsse nonce ......有什么标准吗?

我的代码

$nonce = sha1(mt_rand());

结果

dabddf9dbd95b490ace429f7ad6b55c3418cdd58

这与示例完全不同......我相信这就是这段代码不起作用的原因。

所以我正在做更多的研究,现在我正在使用这个

$NASC = substr(md5(uniqid('the_password_i_am _using', true)), 0, 16);
$nonce = base64_encode($NASC); 

结果

NzJlMDQ4OTAyZWIxYWU5ZA==

现在,它看起来与示例相似,但我仍然从一开始就显示该错误。

有人可以帮帮我吗?

使用soapUI 进行一些进一步的测试。

相同的userID和passwd,设置passwordtype为passwordtext

它正在工作。

有谁知道soapUI如何计算nonce?或者知道soapUI如何通过ws-security?

4

3 回答 3

9

尝试这样的事情

        string usn = "MyUsername";
        string pwd = "MyPassword";

        DateTime created = DateTime.Now.ToUniversalTime();
        var nonce = getNonce();
        string nonceToSend = Convert.ToBase64String(Encoding.UTF8.GetBytes(nonce));
        string createdStr = created.ToString("yyyy-MM-ddTHH:mm:ssZ");
        string passwordToSend = GetSHA1String(nonce + createdStr + pwd);

和功能:

protected string getNonce()
    {
        string phrase = Guid.NewGuid().ToString();
        return phrase;

    }

    protected string GetSHA1String(string phrase)
    {
        SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
        byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
        string test = Convert.ToString(hashedDataBytes);
        return Convert.ToBase64String(hashedDataBytes);
    }
于 2013-09-21T12:29:43.340 回答
2

由于uniqid()基于伪随机数生成器,它不提供足够的熵。随机值的Siehe熵不足

$nonce = base64_encode( bin2hex( openssl_random_pseudo_bytes( 16 ) ) );

如果您没有 OpenSSL 模块,请尝试此后备以mcrypt_create_iv()查看:

https://github.com/padraic/SecurityMultiTool/blob/master/library/SecurityMultiTool/Random/Generator.php

于 2015-07-03T12:19:11.903 回答
0

Microsoft 将WS-Security随机数定义为:

The nonce is 16 bytes long and is passed along as a base64 encoded value.

以下 PHP 代码生成遵循 Microsoft .Net WS-Security 标准的代码:

    $prefix = gethostname();
    $nonce = base64_encode( substr( md5( uniqid( $prefix.'_', true)), 0, 16));

一些没有 $prefix 的测试是成功的,但是此代码的生产版本使用 $prefix,到目前为止没有遇到任何身份验证问题。此 nonce 代码的原始版本来自以下库(修改了要在 substr 中返回的字符数): http ://code.ronoaldo.net/openemm/src/e25a2bad5aa7/webservices/WSSESoapClient.php#cl -267

于 2013-09-03T17:15:00.853 回答