Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7832597
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T12:18:19+00:00 2026-06-02T12:18:19+00:00

I am implementing an API from a bank and they require a security token

  • 0

I am implementing an API from a bank and they require a security token to be provided. In the header of every soap message there is something which looks as follows:

<soapenv:Header>
  <tpw:BinarySecurityToken ValueType="MAC" Id="DesMacToken" EncodingType="Base64" Value="**xvz**"/>
</soapenv:Header>

According to their documentation I need to generate an 8 byte MAC value on the body of each message. The MAC is generated by the CBC-MAC algorithm and DES as the block cipher. The contents of the soapenv:Body tag of each message is used as the data for the MAC calculation.

So my question is how do I get WCF to do this? I have put the following code together to create the MAC value, but am unsure how to get this into the header of every message.

private string GenerateMAC(string SoapXML)
        {
            ASCIIEncoding encoding = new ASCIIEncoding();

            //Convert from Hex to Bin
            byte[] Key = StringToByteArray(HexKey);
            //Convert String to Bytes
            byte[] XML = encoding.GetBytes(SoapXML);

            //Perform the Mac goodies
            MACTripleDES DesMac = new MACTripleDES(Key);
            byte[] Mac = DesMac.ComputeHash(XML);

            //Base64 the Mac
            string Base64Mac = Convert.ToBase64String(Mac);

            return Base64Mac;
        }

        public static byte[] StringToByteArray(string Hex)
        {
            if (Hex.Length % 2 != 0)
            {
                throw new ArgumentException();
            }

            byte[] HexAsBin = new byte[Hex.Length / 2];
            for (int index = 0; index < HexAsBin.Length; index++)
            {
                string bytevalue = Hex.Substring(index * 2, 2);
                HexAsBin[index] = Convert.ToByte(bytevalue, 16);
            }

            return HexAsBin;
        }

Any help will be greatly appreciated.

More info:
The bank has provided a WSDL which I have used as a service reference. An example of a response that is sent:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="LogonRequest", WrapperNamespace="http://webservice.com", IsWrapped=true)]
public partial class LogonRequest {

    [System.ServiceModel.MessageHeaderAttribute(Namespace="http://webservice.com")]
    public DataAccess.BankService.BinarySecurityToken BinarySecurityToken;

The BinarySecurityToken (that goes in the header) looks as follows:

 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://webservice.com")]
    public partial class BinarySecurityToken : object, System.ComponentModel.INotifyPropertyChanged {

        private string valueTypeField;

        private string idField;

        private string encodingTypeField;

        private string valueField;

        public BinarySecurityToken() {
            this.valueTypeField = "MAC";
            this.idField = "DesMacToken";
            this.encodingTypeField = "Base64";
        }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-02T12:18:21+00:00Added an answer on June 2, 2026 at 12:18 pm

    I had to do something like this recently and what I ended up doing was creating a behaviour that implemented IClientMessageInspector and used the BeforeSendRequest method to create data for my header and then populate it into the SOAP request.

    public class SoapHeaderBehaviour : BehaviorExtensionElement, IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState) { }
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        { 
            var security = new Security();   // details irrelevant
            var messageHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", security, new ConcreteXmlObjectSerializer(typeof(Security)), true);
            request.Headers.Add(messageHeader);
    
            return null;
        }
    
        protected override object CreateBehavior() { return new SoapHeaderBehaviour(); }
        public override Type BehaviorType { get { return GetType(); } }
    }
    

    ConcreteXmlObjectSerializer is a class I found on the internet somewhere (unfortunately can’t seem to find it right now) that just worked. Here is the code for that:

    public class ConcreteXmlObjectSerializer : XmlObjectSerializer
    {
        readonly Type objectType;
        XmlSerializer serializer;
    
        public ConcreteXmlObjectSerializer(Type objectType)
            : this(objectType, null, null)
        {
        }
    
        public ConcreteXmlObjectSerializer(Type objectType, string wrapperName, string wrapperNamespace)
        {
            if (objectType == null)
                throw new ArgumentNullException("objectType");
            if ((wrapperName == null) != (wrapperNamespace == null))
                throw new ArgumentException("wrapperName and wrapperNamespace must be either both null or both non-null.");
            if (wrapperName == string.Empty)
                throw new ArgumentException("Cannot be the empty string.", "wrapperName");
    
            this.objectType = objectType;
            if (wrapperName != null)
            {
                XmlRootAttribute root = new XmlRootAttribute(wrapperName);
                root.Namespace = wrapperNamespace;
                this.serializer = new XmlSerializer(objectType, root);
            }
            else
                this.serializer = new XmlSerializer(objectType);
        }
    
        public override bool IsStartObject(XmlDictionaryReader reader)
        {
            throw new NotImplementedException();
        }
    
        public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
        {
            Debug.Assert(serializer != null);
            if (reader == null) throw new ArgumentNullException("reader");
            if (!verifyObjectName)
                throw new NotSupportedException();
    
            return serializer.Deserialize(reader);
        }
    
        public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
        {
            throw new NotImplementedException();
        }
    
        public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            if (writer.WriteState != WriteState.Element)
                throw new SerializationException(string.Format("WriteState '{0}' not valid. Caller must write start element before serializing in contentOnly mode.",
                    writer.WriteState));
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream, Encoding.UTF8))
                {
                    serializer.Serialize(bufferWriter, graph);
                    bufferWriter.Flush();
                    memoryStream.Position = 0;
                    using (XmlReader reader = new XmlTextReader(memoryStream))
                    {
                        reader.MoveToContent();
                        writer.WriteAttributes(reader, false);
                        if (reader.Read()) // move off start node (we want to skip it)
                        {
                            while (reader.NodeType != XmlNodeType.EndElement) // also skip end node.
                                writer.WriteNode(reader, false); // this will take us to the start of the next child node, or the end node.
                            reader.ReadEndElement(); // not necessary, but clean
                        }
                    }
                }
            }
        }
    
        public override void WriteEndObject(XmlDictionaryWriter writer)
        {
            throw new NotImplementedException();
        }
    
        public override void WriteObject(XmlDictionaryWriter writer, object graph)
        {
            Debug.Assert(serializer != null);
            if (writer == null) throw new ArgumentNullException("writer");
            serializer.Serialize(writer, graph);
        }
    }
    

    This is then hooked into the WCF client endpoint via the config file in 3 steps (all under the system.serviceModel node:

    Register the extension

    <extensions>
      <behaviorExtensions>
        <add name="ClientSoapHeaderAdderBehaviour"
            type="MyNamespace.SoapHeaderBehaviour, MyAssembly, Version=My.Version, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
    

    Create an endpoint behaviour using it

    <behaviors>
      <endpointBehaviors>
        <behavior name="MyEndpointBehaviours">
          <ClientSoapHeaderAdderBehaviour />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    

    Attach your endpoint behaviour to your client endpoint

    <client>
      <endpoint address="blah" binding="basicHttpBinding"
        bindingConfiguration="blah" contract="blah"
        name="blah"
        behaviorConfiguration="MyEndpointBehaviours"/>
    </client>
    

    Hope this helps you.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

im writing a free tool for SEO... implementing an api from seomoz and the
I'm implementing a generic restful api in WCF. I require access to a generic
I'm working on implementing a website's API in an Android app. There's a part
I'm using IBM's Tivoli Security Policy Manager with a custom PIP (implementing com.ibm.tscc.rtss.authz.api.IExternalFinder ).
I'm implementing the Graph API in Facebook to retrieve data as JSON from an
I'm implementing history API for my web app and of course IE doesn't support
I'm implementing an API for a CMS. Clients are accessing the API via a
I am implementing a rest API and now I have to execute following request
I am implementing new Balanced API for the payment, and starting to think about
I'm implementing a REST API using ASP.NET MVC, and a little stumbling block has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.