Decrypt 3DES DUKPT per the ANSI X9.24 part 1 standard

3.5k Views Asked by At

I have a Magtek uDynamo and am trying to decrypt track 1. I have read the below and understand a little bit but don't know how to actually decrypt the data. The vendor said to use the ANSI test key to decrypt but I can't find anything on that. I have the KSN, session, and serial numbers. I have also tried some Java code I found, but it doesn't seem to work. It returns null or possibly I'm putting in the wrong BDK. I'm just using the serial number for that which I read somewhere. I'm doing this on Android. Preferably I would like code that runs on the server not on the device so it goes encrypted across the line along with HTTPS.

How ciphertext was generated in card reader using DUKPT encryption?

3DES-DUKPT (CBC) decryption confirmation

https://github.com/yinheli/dukpt/blob/master/src/main/java/com/yinheli/tool/DukptDecrypt.java

Update I'm looking to decrypt 3DES DUKPT per the ANSI X9.24 part 1 standard

I'm using this https://github.com/camcima/dukpt-php/tree/e8fceb4df8757e7e097c435221b4e93e097d3c9f

I had to update the files and make sure I got the most recent phpseclib and it runs but the data comes out like C��� ������4A�fr���( Wb������f�7z�n:�w�9��,��f7�,m=�z�CRW�

I must be missing something. I've tried different modes and I'm trying to look for encoding. Please let me know if you have a solution or ideas. Also their test data does work so I'm not sure what the difference is between mine and theirs

Code I'm running index.php in the root:

include 'vendor/autoload.php';

use DUKPT\DerivedKey;
use DUKPT\KeySerialNumber;
use DUKPT\Utility;

$encryptedHexData = 'de8bfe769dca885cf3cc312135fe2cccfacf176235f4bdee773d1865334315ed2aefcab613f1884b5d63051703d5a0e2bd5d1988eeabe641bd5d1988eeabe641';
$ksn = '00000232100117e00027';
$bdk = '0123456789ABCDEFFEDCBA9876543210';

$key = new KeySerialNumber($ksn);
$encryptionKey = DerivedKey::calculateDataEncryptionRequestKey($key, $bdk);
$actual = Utility::hex2bin(Utility::removePadding(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true)));


echo $encryptionKey.'<br />';

echo $actual.'<br /><br />';
1

There are 1 best solutions below

0
On

With a proper BDK and KSN all you need to do now is try the different modes.

Right now you are using DerivedKey::calculateDataEncryptionRequestKey($key, $bdk);

You need to try the other modes to figure out which one your device is using. Here is the code I used to find the correct result for my device.

include 'vendor/autoload.php';

use DUKPT\DerivedKey;
use DUKPT\KeySerialNumber;
use DUKPT\Utility;

$encryptedHexData = 'C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12';
$ksn = 'FFFF9876543210E00008';
$bdk = '0123456789ABCDEFFEDCBA9876543210';

$key = new KeySerialNumber($ksn);

$encryptionKey = DerivedKey::calculatePinEncryptionKey($key, $bdk);
$decryptedOutput = Utility::hex2bin(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true));
echo '<br /><br />Pin Encryption Key: '.$encryptionKey;
echo '<br />Decrypted Output: '.$decryptedOutput;

$encryptionKey = DerivedKey::calculateMacRequestKey($key, $bdk);
$decryptedOutput = Utility::hex2bin(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true));
echo '<br /><br />Mac Request Key: '.$encryptionKey;
echo '<br />Decrypted Output: '.$decryptedOutput;

$encryptionKey = DerivedKey::calculateMacResponseKey($key, $bdk);
$decryptedOutput = Utility::hex2bin(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true));
echo '<br /><br />Mac Response Key: '.$encryptionKey;
echo '<br />Decrypted Output: '.$decryptedOutput;

$encryptionKey = DerivedKey::calculateDataEncryptionRequestKey($key, $bdk);
$decryptedOutput = Utility::hex2bin(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true));
echo '<br /><br />Data Encryption Request Key: '.$encryptionKey;
echo '<br />Decrypted Output: '.$decryptedOutput;

$encryptionKey = DerivedKey::calculateDataEncryptionResponseKey($key, $bdk);
$decryptedOutput = Utility::hex2bin(Utility::tripleDesDecrypt($encryptedHexData, $encryptionKey, true));
echo '<br /><br />Data Encryption Response Key: '.$encryptionKey;
echo '<br />Decrypted Output: '.$decryptedOutput;

So for this BDK and KSN the below is the resulting output.

Pin Encryption Key: 27F66D5244FF621EAA6F6120EDEB427F
Decrypted Output: %B5452300551227189^HOGAN/PAUL ^08043210000000725000000?

Mac Request Key: 27F66D5244FF9DE1AA6F6120EDEBBD80
Decrypted Output: W����U�P�TfB/`����þ&��f��3y;�U�Zy��UK�[��s�;�>�[�b

Mac Response Key: 27F66D52BBFF62E1AA6F612012EB4280
Decrypted Output: b�K2a�S0��9�Mb-����*L�J���� ��s�\���H�����=���e�]�,���Hwq�

Data Encryption Request Key: C39B2778B058AC376FB18DC906F75CBA
Decrypted Output: RA]�ԅⱰQ���'v}b��h��St�����?� lu/�ٵ�P��!���6�� �

Data Encryption Response Key: 846E267CB822197406DA2B161191C6E4
Decrypted Output: ��,�B^FZ�� ςs�c���*E�4��0��ǂ}����6`-P�b�ʞ̳aصĬ�&���+��