8

I am trying to use javascript to encode data with AES-256-CBC and php mcrypt libraries to decode, and vise versa.

I am aware of the problematic nature of javascript and the fact that anyone sees the key, but I am using javascript a scripting tool for non-web environment - so not worried about it.

I found pidder https://sourceforge.net/projects/pidcrypt/

and encrypted some data with the demo page, then tried to decrypt it via php, but something is wrong and I can't seem to find what... I am using the same key with both ends, a 32 byte string

any pointers will be appreciated

~~~

$encrypted = "string after pidder encryption";  

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_256,'',MCRYPT_MODE_CBC,'');    

$iv_size = mcrypt_enc_get_iv_size($cipher);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

mcrypt_generic_init($cipher, $key, $iv);


$encrypted = base64_decode($encrypted);

echo "after b64decode: " . $encrypted . "\n\n\n";

$encrypted = mdecrypt_generic($cipher, $encrypted);

echo "decrypt:" . $encrypted;

~~~

2
  • Hmm, in my eyes MCRYPT_RIJNDAEL_256 is not AES-256. Might not be the only problem in your code, but maybe a start. Commented Jun 19, 2011 at 20:08
  • Rijndael is AES, that's just different names of algorithm. Commented Jun 19, 2011 at 20:37

5 Answers 5

1

Try MCRYPT_RIJNDAEL_128 with a 32-byte key for AES-256.

AES is a 128-bit block cipher that supports 128-, 192-, and 256-bit keys. Rijndael-256 is a 256-bit block cipher and AES. AES is a 128-bit block specification for Rijndael.

Sign up to request clarification or add additional context in comments.

Comments

0

Pidder uses key derivation function to get the key from password (it should be HMAC-SHA1, i guess), but you seems to use plain password as a key.

2 Comments

I already have a hex key , 32 byte long, I want to feed both pidder and mcrypt with it, but it does seem pidder manipulates it first.. any idea how to get them to "speak" ?
I can also use a different javascript library to "speak" with mcrypt on php, any working code example ?
0

Javascript Mcrypt plays well with PHP mcrypt. You could use that instead of pidder.

Comments

0

Your code is sequential, honestly, I dont tried to fix, but I have a function that work well and can help you.

    /**
 * Encrypt Token
 *
 * @param unknown $text         
 */
private function rijndaelEncrypt($text) {
    $iv_size = mcrypt_get_iv_size ( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB );
    $iv = mcrypt_create_iv ( $iv_size, MCRYPT_RAND );
    $key = 'your key';
    return base64_encode ( mcrypt_encrypt ( MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv ) );
}

/**
 * Decrypt
 *
 * @param unknown $text         
 */
private function rijndaelDecrypt($text) {
    $iv_size = mcrypt_get_iv_size ( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB );
    $iv = mcrypt_create_iv ( $iv_size, MCRYPT_RAND );
    $key = 'your key';
    // I used trim to remove trailing spaces
    return trim ( mcrypt_decrypt ( MCRYPT_RIJNDAEL_256, $key, base64_decode ( $text ), MCRYPT_MODE_ECB, $iv ) );
}

See https://www.php.net/manual/en/function.mcrypt-encrypt.php

Comments

0

first of all: MCRYPT_RIJNDAEL_256 is NOT(!) AES-256-CBC, if you want this encryption you have to use MCRYPT_RIJNDAEL_128 with an 265bit aka 32 character key.

This would be the php part:

function decrypt($data, $key) {
    if(32 !== strlen($key)) $key= hash('SHA256', $key, true);

    $data = base64_decode($data);
    $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
    $padding = ord($data[strlen($data) - 1]); 

    return substr($data, 0, -$padding); 
}

This php function includes padding which is an important part, because if the suplied data lenght is not a multiple of the key, you will get something odd.

For decoding we use some of my Node.js scripts with an emulated method of php's str_repeat for the iv:

var crypto = require('crypto'); 

function encrypt(data, key) {
    key = key || new Buffer(Core.config.crypto.cryptokey, 'binary'),
        cipher = crypto.createCipheriv('aes-256-cbc', key.toString('binary'), str_repeat('\0', 16));
    cipher.update(data.toString(), 'utf8', 'base64');
    return cipher.final('base64');
}

function str_repeat(input, multiplier) {
    var y = '';
    while (true) {
        if (multiplier & 1) {
            y += input;
        }
        multiplier >>= 1;
        if (multiplier) {
            input += input;
        } else {
            break;
        }
    }
    return y;
}

NOTE: It is not recommend to use a static IV (Initialization vector)! NOTE: JavaScript part is for Node.js using it's crypto library.

I hope this works for you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.