views:

2965

answers:

4

We are currently transferring our websites from Windows 2003 (32-bit) to Windows 2008 (64-bit) and have hit a problem.

One of our website use the payment gateway HSBC CPI which requires a DLL to be registered(regsvr32.exe), this DLL is then used inside a classic asp website. The problem is the DLL is a 32-bit DLL and so it will not register with the the Windows 2008 operating system.

Is there a way we can wrap this 32 bit dll in a c#.net project so that it's methods are exposed and can be registerd with the OS?

Any help would be very much appreciated.

+3  A: 

You can register the DLL with regsvr32.exe from the C:\Windows\SysWOW64 folder.

However since you can't mix 64/32bit code you'd have to create a C# service running in x86 (see the project properties, platform target) that you can then use from your x64 web app via WCF.

An easier option would be to ask HSBC for a x64 dll.

chris
Thanks chris this works.Unfortunately HSBC do not support 64bit operating systems.
Tim Jarvis
A: 

We hit the same problems with the HSBC Cpi interface.

HSBC don't supply a .Net wrapper, and the COM wrapper can not be called from a 64bit app.

This makes deploying it from on a 64 server (which probably covers 25% of new production servers) practically imposible.

We looked at some of the approaches listed, but they seemed like a lot of work. In the end after a bit of messing around we came up with our own implementation, which looks something like this.

Use the following Java code to get the intermediate hash

import java.io.Console;
import java.lang.*;
import java.util.*;
import com.clearcommerce.CpiTools.security.HashGenerator;
import com.clearcommerce.CpiTools.security.SecCrypto;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Vector;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Extract {

    /**
     * @param args
     */
    public static void main(String[] args) {
     // TODO Auto-generated method stub
     try
     {
         String encryptedKey = "<YOUR SECRET KEY HERE>";
         if (args.length == 1)
          encryptedKey = args[0];

      HexBinaryAdapter hb = new HexBinaryAdapter();
      SecCrypto sc = new SecCrypto();

      byte abyte0[] = sc.decryptToBinary(encryptedKey);
      System.out.println("New Secret Base64 Encoded : " + new String(Base64Coder.encode(abyte0)));
      System.out.println("New Secret Hex Encoded    : " + hb.marshal(abyte0));
         return;
     }
     catch(Exception ex)
     {
      System.out.println("Error:" + ex.getMessage());
     }
    }
}

Then use the following .net code to calcualte the hash

using System;
using System.Collections.Generic;
using System.Text;

namespace HsbcIntergration
{
    internal static class CpiHashing
    {
     <USE THE VALUE RETURNED FROM THE JAVA CODE HERE>
        private static readonly byte[] _secret = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        public static string ComputeHash(List<string> inputList)
        {
            return ComputeHash(inputList, _secret);
        }

        public static string ComputeHash(List<string> inputList, byte[] secretData)
        {
            List<string> orderedDataToHash = new List<string>(inputList);
            orderedDataToHash.Sort(StringComparer.Ordinal);

            StringBuilder sb = new StringBuilder();
            foreach (string s in orderedDataToHash)
                sb.Append(s);

            List<byte> dataToHash = new List<byte>();
            dataToHash.AddRange(Encoding.ASCII.GetBytes(sb.ToString()));
            dataToHash.AddRange(secretData);

            System.Security.Cryptography.HMAC sha = System.Security.Cryptography.HMACSHA1.Create();
            sha.Key = secretData;
            return Convert.ToBase64String(sha.ComputeHash(dataToHash.ToArray(), 0, dataToHash.Count));
        }
    }
}
Colin
A: 

If you want to register the 32-bit COM dll created using VC++ or Visual Basic 6.0 then you have to follow the steps below without making any changes in the code. It also does not require any compilation to be done and also you do not have to run the IIS in WOW Mode. I have faced this issue few years back and I resolved this issue and it works fine for me.

Scenario:

Let me assume that you have a 3rd party 32-bit COM DLL provided by a vendor. The DLL works fine on 32bit Operating system and the moment you move to a x64 environment it does not work even though you have tried to register it through regsv32.

Also let me assume that the name of the DLL is "ASXUpload.DLL". I will use this name in the solution which I am providing below.

Solution

Please follow the steps below:

  1. First of all if you have already registered the DLL in x64 Operating System the unregister the DLL. To do that just type the following in the run command "regsvr32 /u " something like "regsvr32 /u C:\MyDLL\ASXUpload.DLL". If you have already unregistered the DLL from the x64 OS then no need to run this step.

  2. Also make sure that you have not kept your DLL inside the Windows folder which is normally C:\Windows. For this example I have kept the DLL in the following folder C:\MyDLL.

  3. Now we need to add the COM+ Components using Component Services of Microsoft. To start Component Services, go to Control Panel / Administrative Tools/ Component Services. Once inside component Services, drill down into Computers, then My Computer, then COM+ Applications. Then Right-click on COM+ Applications and choose "New" -> "Application".

  4. At "Welcome to the COM Application Install Wizard" screen, click “Next >”.

  5. Click on “Create an Empty Application” button.

  6. Enter the name. Since my DLL name is ASXUpload.dll so I have typed in the name as “ASXUpload”. When asked "Library or Server", select “Server”.

  7. Click “Next >” button and then choose “This User”.

  8. Enter the User or click Browse to select the user. Clicking Browse is safer, to ensure that the correct domain and spelling are used. Enter the password and confirm the password. Warning, be sure to include the domain/username if required. Click on “Finish”. (Note: We recommend "This User", otherwise, someone must be logged onto the server in order for DLL to run.). In my case I have chosen the domain administrator account. You can also add a Service Account. If you are not sure please consult with your system administrator.

  9. Now “Add Application Roles” screen will appear. Do not add anything just click on the “Next >” button.

  10. Now “Add Users to Role” screen appear. Do not add anything just click on the “Next >” button.

  11. Now you will see that under Component Services -> Computers -> My Computer -> COM+ Application -> you will see the newly added application. In this example the application name would be "ASXUpload". Now drill down the newly added application “ASXUpload” by clicking the “+” icon and you will see “Components”.

  12. Now right-click on “Components” and then choose “New Component”. At "Welcome to the COM Application Install Wizard" screen, click “Next >”.

  13. Click on “Install new component(s)” and now select the DLL which you want to register. In the case it would be “C:\MyDLL\ASXUpload.DLL”.

  14. Once you select the DLL you will see that it will show you the components found. Click on the “Next >” button to proceed and finally hit the “Finish” button to complete.

  15. Now is the tricky part. Right click on the application you have added which you will find under Component Services -> Computers -> My Computer -> COM+ Application. In my case the application name is “ASXUpload”. After you right click on the Application select “Properties”. The application properties window will open up. Click on the “Security” tab. In the Security tab make sure that under “Authorization” section the checkbox “Enforce access checks for this application” is unchecked.

Under “Security Level” section select the radio button “Perform access checks only at the process level. Security property will not be included on the object context. COM+ security call context will not be available.”

Make sure that option “Apply restriction policy” is unchecked.

Set “Impersonate Level” to “Anonymous”

  1. If you want to access the DLL from web Application then make sure that you add the IUSR and IWAM account. To do this go to COM+ Application -> Application Name (In this case it will be ASXUpload) -> Roles -> CreateOwner -> Users. Right click on the Users and add the IUSR and IWAM account used by Internet Information Server.

  2. Also set the NTFS permission on the folder where you kept the DLL. In this case I have kept the DLL inside the folder C:\MyDLL. Now right click on the folder “MyDLL” and go to the security tab and then add the IUSR and IWAM account.

This is all you need to do and you should be able to consume the DLL.

I have used this technique twice in two different organizations I have worked in the past on the Production Environment and it works without any issues. First I tried this in the year 2005 and then I used it again in 2008.

Let me know if you are facing any issues.

Sarbashish Bhattacharjee
A: 

Thanks realy for this great pieze of gold.... clear, accurate and easy. You saved my day!

miguel