5

I am getting an error while trying to send a soap request (soapCall) to the server.

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

I need to send the ws-security header

<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>

After a lot of research I think the issue I got is the nonce didnt meet the requirement. As I am making up the soap header looks like the example I got. The only unknown element is to calculating this nonce...

From the example nonce I got, its a set of 24 numbers + alphabet + special character

Something like this

ZTQ3YmJjZmM1ZTU5ODg3YQ==

But however, I am not too sure how do you calculate the wsse nonce from php...is there any standard?

the code I had

$nonce = sha1(mt_rand());

Result

dabddf9dbd95b490ace429f7ad6b55c3418cdd58

which is something completely different than the example...and I believe this is the reason why this code is not working.

So I am doing more research and now I am using this

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

Result

NzJlMDQ4OTAyZWIxYWU5ZA==

Now, it looks similar to the example but I still getting that error showed from the beginning.

Can someone give me a hand please?

some further testing with soapUI.

same userID and passwd, set the passwordtype to passwordtext

and it is working.

is anyone know how do the soapUI calculate the nonce? or have any idea how soapUI passing the ws-security?

EXphpworld
  • 53
  • 1
  • 1
  • 6
  • Did you get this resolved? I am stuck with the same issue except I have $dateCreated = date('Y/m/d H:i:s'); $nonce = base64_encode(sha1((mt_rand() . $dateCreated . self::PASSWORD))); – Jed Apr 02 '20 at 15:59

3 Answers3

10

try something like this

        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);

and functions:

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);
    }
Lucky Lefty
  • 347
  • 1
  • 8
2

As uniqid() is based on a Pseudo-Random Number Generator, it does not provide enough entropy. Siehe Insufficient Entropy For Random Values

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

If you don't have the OpenSSL module try this fallback to mcrypt_create_iv() see:

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

nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
PiTheNumber
  • 22,828
  • 17
  • 107
  • 180
0

Microsoft defines the WS-Security nonce as:

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

The following PHP code generates a code that follows the Microsoft .Net WS-Security Standard:

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

Some testing with no $prefix was successful, but the production version of this code uses the $prefix with no authentication problems encountered so far. The original version of this nonce code came from the following library (with a modification to the number of characters to return in substr): http://code.ronoaldo.net/openemm/src/e25a2bad5aa7/webservices/WSSESoapClient.php#cl-267

MD3
  • 81
  • 2
  • 6
  • Thanks, but still no luck, I still couldnt connect to the external server. – EXphpworld Dec 05 '13 at 20:40
  • Can you paste the complete error? To quickly test if the certificate is your problem, set `CURLOPT_SSL_VERIFYPEER` to `FALSE` and make a cURL request. Do you have access to your PHP logs? Check there for more information. There are a lot of variables regarding SSL: Is the SOAP server's SSL Certificate publicly signed (StartSSL, GoDaddy, etc)? If not, you'll need to download a copy and install it locally. Does `phpinfo()` report that you have OpenSSL installed? If you're on Windows, do you have the CA Bundle installed correctly for cURL / OpenSSL (http://curl.haxx.se/docs/sslcerts.html)? – MD3 Dec 07 '13 at 17:51