Kryptronic Software Support Forum

You are viewing this forum as a guest. Login to an existing account, or create a new account, to reply to topics and to create new topics.

#1 03-15-2010 10:57:59

karlconnor
Member
Registered: 02-25-2010
Posts: 10

HSBC Communication Error Urgent Help Needed

Hi,

I have just installed the latest version of Europacart and have integrated with the latest version of Joomla.  All looks great, Paypal works but HSBC doesn't.  I have put in my HSBC supplied Hash number and my merchant number and have checked this with them.  I keep getting a communication error.  When you click on "Enter Payment Information" then press the continue button it goes to HSBC and says communication error :

Communication Failure
*

We have been unable to proceed with your transaction due to a communication failure.

Please Close your browser window and confirm the status of your order with the merchant

Any ideas cannot get it to work and am launching the site at the end of the week HELP smile

Offline

 

#2 03-20-2010 11:58:44

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

There are lots of reasons why the HSBC link won't work. Search in the CCP6 forum for some of them.

Have you checked whether you are in test or production mode?

You may also still need to change the line

$tmp[7] = $order['order']['epochorder'] * 1000;

to

$tmp[7] = $order['order']['epochorder']  . '000';

to prevent an illegal timestamp on the comms to HSBC's page, as has been reported many times but is still unfixed.

Finally, I believe that you need to be using a secure link to HSBC - is your site running in https: mode?

Offline

 

#3 03-22-2010 05:06:39

karlconnor
Member
Registered: 02-25-2010
Posts: 10

Re: HSBC Communication Error Urgent Help Needed

Hi,

I am running is https, I have checked the hash and merchant number details with hsbc and i have edited the line you suggested.  Still has same error?

Any thoughts?

Offline

 

#4 03-29-2010 07:37:15

dansmith490
Member
From: Barrow, Bury St Edmunds
Registered: 11-10-2008
Posts: 154
Website

Re: HSBC Communication Error Urgent Help Needed

i am also getting this error, did you manage to sort this?

Offline

 

#5 05-02-2010 18:58:07

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

I'm looking into this as I now have a problem where I didn't before. Could you please create a small php script as below, run it and post the results?

Code:

<pre>
<?
   echo "PHP_INT_MAX is " . PHP_INT_MAX . "\n";
   echo "PHP_INT_SIZE is " . PHP_INT_SIZE . "\n";
?>
</pre>

Offline

 

#6 05-02-2010 20:07:36

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

I now have a fix for my system, which is a 64-bit build of PHP rather than the current standard of 32-bits. If the reply to the small script above is

Code:

PHP_INT_MAX is 2147483647
PHP_INT_SIZE is 4

then you don't have the same problem that I've just fixed. If is says

Code:

PHP_INT_MAX is 9223372036854775807
PHP_INT_SIZE is 8

then you might have.

I'll post the full code if anyone else is seeing the HSBC Error code 10 (invalid hash) on a 64-bit system and wants to try it.

Offline

 

#7 05-04-2010 07:47:53

dansmith490
Member
From: Barrow, Bury St Edmunds
Registered: 11-10-2008
Posts: 154
Website

Re: HSBC Communication Error Urgent Help Needed

Hello,

mine does say

PHP_INT_MAX is 9223372036854775807
PHP_INT_SIZE is 8

I am seeing the error code 10, did you get a fix for this?
Thanks

Offline

 

#8 05-04-2010 15:16:30

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

The problem I had was with the file hsbc_crypto.php in {private}/apps/gbu0/GBU_OLP/ext and was caused by left and right shifting integer values to create a key. The algorithm assumes that an integer is 32 bits long. Therefore a left shift will lose bits to the left; if a large number is shifted it may reduce its value if the remaining bits are so arranged. Similarly a right shift will keep its sign but lose bits to the right.

Now with a 64-bit machine this left shifting does not lose the bits in the same way  as before, because they just move up the chain into their correct position. Therefore the result of a left shift is different. For example, on a 32-bit OS the result of one operation was 0x728B4536, the same operation on a 64-bit machine gave 0x26CC000054474536.

There is another issue caused by a strange operation, a negative left-shift, that is used in the crypto code. A negative left shift of 16 (eg $right ^=  ($temp << -16); ) needs to be replaced by a shift of -48 (ie $right ^=  ($temp << -48); )

Finally, the results of each operation need to be stripped to 32 bits before the next step.

I am lucky in that I have both 32-bit and 64-bit machines available to compare results from each step in the code (lots of "echo"s involved).

Please note that I am running CCP6 not CCP7, so you may need to modify my fixes if the code is different in CCP7 (don't think that it is).

To fix the code, backup the hsbc_crypto.php file and then edit it. Find the function at line 316 called des_createKeys and rename it (eg to des_createKeys32). Go to the bottom of the file and insert the following code before line 395 ("////TEST////")

Code:

//des_createKeys NEW for 32 or 64 bit systems
//Piers Glydon 02May2010
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys ($key) {
  //echo "Function des_createKeys (in) \$key=$key\n";
  //declaring this locally speeds things up a bit
  $pc2bytes0  = array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
  $pc2bytes1  = array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
  $pc2bytes2  = array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
  $pc2bytes3  = array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
  $pc2bytes4  = array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
  $pc2bytes5  = array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
  $pc2bytes6  = array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
  $pc2bytes7  = array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
  $pc2bytes8  = array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
  $pc2bytes9  = array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
  $pc2bytes10 = array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
  $pc2bytes11 = array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
  $pc2bytes12 = array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
  $pc2bytes13 = array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
  $masks = array (4294967295,2147483647,1073741823,536870911,268435455,134217727,67108863,33554431,16777215,8388607,4194303,2097151,1048575,524287,262143,131071,65535,32767,16383,8191,4095,2047,1023,511,255,127,63,31,15,7,3,1,0);

  //how many iterations (1 for des, 3 for triple des)
  $iterations = ((strlen($key) >= 24) ? 3 : 1);
  //stores the return keys
  $keys = array (); // size = 32 * iterations but you don't specify this in php
  //now define the left shifts which need to be done
  $shifts = array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
  //other variables
  $m=0;
  $n=0;

  $is64bit = ( 8 == PHP_INT_SIZE ) ? true : false;
  
   //echo "PHP_INT_MAX is " . PHP_INT_MAX . "\n";
   //echo "PHP_INT_SIZE is " . PHP_INT_SIZE . "\n";
   //echo "\$is64bit is $is64bit\n";
  
  
  for ($j=0; $j<$iterations; $j++) { //either 1 or 3 iterations
    $left = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});
    $right = (ord($key{$m++}) << 24) | (ord($key{$m++}) << 16) | (ord($key{$m++}) << 8) | ord($key{$m++});
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );

    $temp = (($left >> 4 & $masks[4]) ^ $right) & 0x0f0f0f0f; $right ^= $temp; $left ^= ($temp << 4);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );
    
    $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp; 
    $right ^= $is64bit ? ($temp << -48) : ($temp << -16) ;
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );
    
    $temp = (($left >> 2 & $masks[2]) ^ $right) & 0x33333333; $right ^= $temp; $left ^= ($temp << 2);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );
    
    $temp = (($right >> 16 & $masks[16]) ^ $left) & 0x0000ffff; $left ^= $temp;
    $right ^= $is64bit ? ($temp << -48) : ($temp << -16) ;
    $left = intval32bits( $left ) ; $right = intval32bits ( $right );  $temp = intval32bits( $temp );
    
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );
    
    $temp = (($right >> 8 & $masks[8]) ^ $left) & 0x00ff00ff; $left ^= $temp; $right ^= ($temp << 8);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );
    
    $temp = (($left >> 1 & $masks[1]) ^ $right) & 0x55555555; $right ^= $temp; $left ^= ($temp << 1);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right ); $temp = intval32bits( $temp );

    //the right side needs to be shifted and to get the last four bits of the left side
    $temp = ($left << 8) | (($right >> 20 & $masks[20]) & 0x000000f0);
    $left = intval32bits( $left ) ; $right = intval32bits ( $right );  $temp = intval32bits( $temp );
    //left needs to be put upside down
    $left = ($right << 24) | (($right << 8) & 0xff0000) | (($right >> 8 & $masks[8]) & 0xff00) | (($right >> 24 & $masks[24]) & 0xf0);
    $right = $temp;
    $left = intval32bits( $left ) ; $right = intval32bits ( $right );

    //now go through and perform these shifts on the left and right keys
    for ($i=0; $i < count($shifts); $i++) {
      //shift the keys either one or two bits to the left
      if ($shifts[$i] > 0) {
         $left = (($left << 2) | ($left >> 26 & $masks[26]));
         $right = (($right << 2) | ($right >> 26 & $masks[26]));
      } else {
         $left = (($left << 1) | ($left >> 27 & $masks[27]));
         $right = (($right << 1) | ($right >> 27 & $masks[27]));
      }
      $left = $left & -0xf;
      $right = $right & -0xf;

      //now apply PC-2, in such a way that E is easier when encrypting or decrypting
      //this conversion will look like PC-2 except only the last 6 bits of each byte are used
      //rather than 48 consecutive bits and the order of lines will be according to 
      //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
      $lefttemp = $pc2bytes0[$left >> 28 & $masks[28]] | $pc2bytes1[($left >> 24 & $masks[24]) & 0xf]
              | $pc2bytes2[($left >> 20 & $masks[20]) & 0xf] | $pc2bytes3[($left >> 16 & $masks[16]) & 0xf]
              | $pc2bytes4[($left >> 12 & $masks[12]) & 0xf] | $pc2bytes5[($left >> 8 & $masks[8]) & 0xf]
              | $pc2bytes6[($left >> 4 & $masks[4]) & 0xf];
      $righttemp = $pc2bytes7[$right >> 28 & $masks[28]] | $pc2bytes8[($right >> 24 & $masks[24]) & 0xf]
                | $pc2bytes9[($right >> 20 & $masks[20]) & 0xf] | $pc2bytes10[($right >> 16 & $masks[16]) & 0xf]
                | $pc2bytes11[($right >> 12 & $masks[12]) & 0xf] | $pc2bytes12[($right >> 8 & $masks[8]) & 0xf]
                | $pc2bytes13[($right >> 4 & $masks[4]) & 0xf];
      $temp = (($righttemp >> 16 & $masks[16]) ^ $lefttemp) & 0x0000ffff; 
      $keys[$n++] = $lefttemp ^ $temp; $keys[$n++] = $righttemp ^ ($temp << 16);
    }
  } //for each iterations
  //return the keys we've created
  return $keys;
} //end of des_createKeys

//http://stackoverflow.com/questions/300840/force-php-integer-overflow/2123458#2123458
//Vadzim Struk http://stackoverflow.com/users/257425/vadzim-struk
function intval32bits($value)
{
    $value = ($value & 0xFFFFFFFF);

    if ($value & 0x80000000)
        $value = -((~$value & 0xFFFFFFFF) + 1);

    return $value;
}

Save the new file back to hsbc_crypto.php and you should be sorted.

The HSBC guide gives examples of what the hashed values should be, given a known hash key and input array. I've written this up into a small script which should show whether your new code is working. Stick this on your webserver, modify the path in line 3 to point to your hsbc_crypto.php, and run it. You could try this before and after modifying the crypto file to see whether it has made a difference.

Code:

<pre>
<?php
//PG 02May2010
$path_to_crypto = "/home/xxx/yyy/apps/gbu0/GBU_OLP/ext/hsbc_crypto.php";
include_once ( $path_to_crypto );
$keyHSBC = "zEeWQNKelqPE2DRFueuDq1QrASjux2lM";
$key = $keyHSBC;
$array = array();
$array[] = "aaa";
echo "First hash should be m4uGmXow+lcJYycNrbM7M8xS3No=\n";
echo "First hash is        " .  generateHash ( $array , $key );
$array[] = "bbb";
echo "\n\nSecond hash should be zaM6DPT7GkEJtg2OWYzSePUa0rc=\n";
echo "Second hash is        " .  generateHash ( $array , $key );
$array[] = "ccc ddd";
echo "\n\nThird hash should be 1sMZc6TaxcMnQthq2Dp0QKe7obk=\n";
echo "Third hash is        " .  generateHash ( $array , $key );
$array[] = "eee fff ggg";
echo "\n\nFourth hash should be 6FLZlCBhHTj5Tr9XbgFhuZVsh7M=\n";
echo "Fourth hash is        " .  generateHash ( $array , $key );
?>
</pre>

Hope this helps - if not, you have another problem! This fixed it for me though.

Offline

 

#9 05-06-2010 15:54:07

karlconnor
Member
Registered: 02-25-2010
Posts: 10

Re: HSBC Communication Error Urgent Help Needed

Hi,

Tried the above, now I get relayed back to my site and see the following in red at the top of the page:

"Unfortunately, we are unable to accept your transaction. There may be a problem with the payment information you entered, or our online processor may be experiencing technical difficulties at the present time. You can attempt to process your order again, or contact us to discuss other payment options."

Offline

 

#10 05-06-2010 17:04:57

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

karlconnor wrote:

"Unfortunately, we are unable to accept your transaction. There may be a problem with the payment information you entered, or our online processor may be experiencing technical difficulties at the present time. You can attempt to process your order again, or contact us to discuss other payment options."

Are you getting the correct hash generated, according to the small script I posted? Are you running a 64-bit or 32-bit OS?

HSBC will tell you the reason that the transaction failed if you call them on the phone. A code is also returned from the bank back to your site - you will need to set debug level 1 or 2 to see this value. I have added code which emails to me the return code and order number every time the response comes back from the bank. You can then look up what the code means according to the table in your documentation, or see post https://forum.kryptronic.com/viewtopic.php?id=22971

However, I'm sorry but as I'm running CCP6 not CCP7 I can't really offer much more help here, much as I'd love to. These fixes solved my most recent issue with HSBC, one of many!

Offline

 

#11 05-07-2010 06:36:26

karlconnor
Member
Registered: 02-25-2010
Posts: 10

Re: HSBC Communication Error Urgent Help Needed

HSBC tell me that the timestamp is coming through as zero and it should be 13 digits?

Offline

 

#12 05-07-2010 06:39:12

bbac
Member
From: Bristol, UK
Registered: 08-25-2008
Posts: 141

Re: HSBC Communication Error Urgent Help Needed

Looks like you may have made a mistake when making the change in step 2 of this thread.

Offline

 

Board footer