3

I'm using the following code to encrypt information that will be passed to an external site on the end of the link URL. Right now it's able to do the encrypting and decrypting itself, but when I go to online Decryptors (online-domain-tools.com, tools4noobs.com) I'm seeing extra symbols added or it's not showing the right content whatsoever. Of course I'm new to this. What I have, I have pieced together from other questions (php-equivalent-for-java-triple-des-encryption-decryption, php-equivalent-encryption-decryption-tripledes, php-encrypt-decrypt-with-tripledes-pkcs7-and-ecb). Thanks for any help or direction!

I can only use 3DES with CBC.

PHP Code:

$key = "12AB12AB12AB12AB12AB12AB";
$iv = "12AB12AB";
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');

// MESSAGE
$message = "email=billysmith@afakeemail.com&account=987654321&role=2";
echo 'Message:::  ' .$message .'<br />';

// ENCRYPTED
$encrypted = Encryptor($message);
echo 'Encrypted:::  ' .$encrypted .'<br />';

// DECRYPTED
$decrypted = Decryptor($encrypted);
echo 'Decrypted:::  ' .$decrypted .'<br />';

function Encryptor($buffer) {
  global $key, $iv, $cipher;

  // get the amount of bytes to pad
  $extra = 8 - (strlen($buffer) % 8);

  // add the zero padding
  if($extra > 0) {
    for($i = 0; $i < $extra; $i++) {
      $buffer .= "\0";
    }
  }
  mcrypt_generic_init($cipher, $key, $iv);
  $result = bin2hex(mcrypt_generic($cipher, $buffer));
  mcrypt_generic_deinit($cipher);
  return $result;
}

function Decryptor($buffer) {
  global $key, $iv, $cipher;

  mcrypt_generic_init($cipher, $key, $iv);
  $result = rtrim(mdecrypt_generic($cipher, hex2bin($buffer)), "\0");
  mcrypt_generic_deinit($cipher);
  return $result;
}

function hex2bin($data)
{
  $len = strlen($data);
  return pack("H" . $len, $data);
} 
Community
  • 1
  • 1
CJdriver
  • 458
  • 7
  • 20

1 Answers1

1

To be short: Your code is correct. You can't test your encryption with provided tools.

Both tools do not allow to enter your IV.

The IV should be unique and can be transferred publicly.

Using wrong IV by decoding gives you wrong part at the beginning of decrypted data.

Here is OO version. It uses zero padding (built in PHP), like your code. It also makes no padding **, if the original message is already aligned.

<?php

$key = "12AB12AB12AB12AB12AB12AB";
$iv = "12AB12AB";

// MESSAGE
$message = "email=billysmith@afakeemail.com&account=987654321&role=22";
echo 'Message:::   ' . $message . PHP_EOL;


$cryptor = new Crypt3Des();

$encryptedMessage = $cryptor->encrypt($message, $key, $iv);
echo 'Encrypted:::  ' . bin2hex($encryptedMessage) . PHP_EOL;

$decryptedMessage = $cryptor->decrypt($encryptedMessage, $key, $iv);
echo 'Decrypted:::  ' . $decryptedMessage . PHP_EOL;

class Crypt3Des
{
    private $cipher;

    public function __construct()
    {
        $this->cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
    }

    public function encrypt($data, $key, $iv)
    {
        mcrypt_generic_init($this->cipher, $key, $iv);
        $result = mcrypt_generic($this->cipher, $data);
        mcrypt_generic_deinit($this->cipher);
        return $result;
    }

    public function decrypt($encryptedData, $key, $iv)
    {
        mcrypt_generic_init($this->cipher, $key, $iv);
        $result = mdecrypt_generic($this->cipher, $encryptedData);
        mcrypt_generic_deinit($this->cipher);
        $result = rtrim($result, "\0");
        return $result;
    }
}


// Before 5.4.0
if (!function_exists('hex2bin')) {
    function hex2bin($data)
    {
        $len = strlen($data);
        return pack("H" . $len, $data);
    }
}
Gennadiy Litvinyuk
  • 1,536
  • 12
  • 21
  • So there is no way to test someone externally decrypting it without having them actually running a test? The reason I'm using online resources is because it's a 3rd party that this will be going to and I want to make sure (I don't look like a dumb-a) they will be able to decrypt it on their end. So as long as the IV is the same for their decryptor the front text will appear correctly? – CJdriver Mar 24 '14 at 16:25
  • Of course you can! I've just found a site with correct test tool: [link](http://www.tero.co.uk/des/test.php) It gives the same output, your code does – Gennadiy Litvinyuk Mar 24 '14 at 18:06
  • Well as long as the key is the proper length it won't use any padding correct? – CJdriver Mar 25 '14 at 13:02
  • No, I meant message padding (zero padding). As long as you have only text load in your messages, it qould work, but not with binary data. – Gennadiy Litvinyuk Mar 25 '14 at 13:04
  • Well for this project it would only be text. Right now, for every encrypt, it will be using the email, account #, and role # information only. What is a better way to pad if I were using binary data though? – CJdriver Mar 25 '14 at 13:07
  • Look for `pkcs5_pad` and `pkcs5_unpad` in other questions referred by you. – Gennadiy Litvinyuk Mar 25 '14 at 13:10
  • So does the code you posted use the right zero padding? (like the pkcs5_pad you recommended) – CJdriver Mar 28 '14 at 16:16
  • My code, like yours, uses zero padding. That is *not* pkcs5 padding. It does not really matter what kind of padding is used so long encyptor and decryptor use the same kind of padding. – Gennadiy Litvinyuk Mar 28 '14 at 19:21
  • Could you add an example of using the pkcs5 padding too? Or the proper way to implement it over zero padding? I've tried modifying it to use that padding but am getting errors now. – CJdriver Apr 03 '14 at 13:28