getNonce() – a C# routine to generate the Nonce code for WS-Security

I created this code to generate a unique Nonce code. This relates back to this post about BizTalk calling a webservice with Basic Authenticiation.

Message Assignment is prior blog was updated to call C# business component:

   "<headers>" + 
   "<wsse:Security mustUnderstand=\"1\" xmlns:wsse=\"\" xmlns:wsu=\"\">" + 
   "<wsse:UsernameToken wsu:Id=\"UsernameToken-E4E3CB1F68472DCF2914369675811859\">" +   
   "  <wsse:Username>" + strServiceBenchUserID + "</wsse:Username>" + 
   "  <wsse:Password Type=\"\">" + strServiceBenchPasswordFromSSO + "</wsse:Password>" + 
   "  <wsse:Nonce EncodingType=\"\">" + Asurion.BusinessCompnents.getNonce() + "</wsse:Nonce>" +
   "  <wsu:Created>" + System.DateTime.UtcNow.ToString("s") + "Z" + "</wsu:Created>" + 
   "</wsse:UsernameToken>" +
   "</wsse:Security>" + 

msgListNewCallRequest(WCF.OutboundCustomHeaders) = xmlDocSoapHeader.OuterXml;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Threading;

namespace Asurion
public static class BusinessCompnents

public static string getNonce()
// Nonce explained here:
// quote: Why is there a nonce? My first thought here was WTF? The username and password are there in clear text, what does the Nonce accomplish?
// The Nonce and created keys are are part of WSE Security specification and are meant to allow the server to detect and prevent replay attacks.
// The hashed nonce should be unique per request which the server can store and check for before running another request thus ensuring that
// a request is not replayed with exactly the same values.
//Random r = new Random();
Random r = RandomProvider.GetThreadRandom(); // better to get unique random number if called mulitple times
DateTime created = DateTime.Now;
string nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(SHA1Encrypt(created + r.Next().ToString())));
return nonce;

public static String SHA1Encrypt(String phrase)
UTF8Encoding encoder = new UTF8Encoding();
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase));
return ByteArrayToString(hashedDataBytes);

public static String ByteArrayToString(byte[] inputArray)
StringBuilder output = new StringBuilder(“”);
for (int i = 0; i < inputArray.Length; i++)
return output.ToString();

} // end class

public static class RandomProvider
private static int seed = Environment.TickCount;

private static ThreadLocal randomWrapper = new ThreadLocal(() =>
new Random(Interlocked.Increment(ref seed))

public static Random GetThreadRandom()
return randomWrapper.Value;

} // end class


Leave a Reply