1

I'm trying to decrypt a string in PHP which was originally encrypted in NodeJS.

PHP:

openssl_decrypt($raw_id, "aes-128-cbc", "s7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m", 0, null)

This seems to always returnfalse.

Encryption in Nodejs:

function encrypt(text) { var cipher = crypto.createCipher('aes-128-cbc', 's7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m'); var encrypted = cipher.update(text, 'utf8', 'hex') encrypted += cipher.final('hex') return encrypted; } function decrypt(text) { var cipher = crypto.createDecipher('aes-128-cbc', 's7UbmJpfm56r6CAC6mz7KVZdRc3Fxc4m'); var decrypted = cipher.update(text, 'hex', 'utf8') decrypted += cipher.final('utf8'); return decrypted; } 

I basically want to encrypt, for example, encrypt("Pizza") in Nodejs, send it to the PHP page (3879f91a59e9a458db62f905b0a488a1), and decrypt it from there (openssl_decrypt: return Pizza).

I know this code is not safe, since I'm not using an IV but I'm not sure how to add one.

1 Answer 1

1

Your method is not secure and can also be victim to man in the middle attacks, you should always use a IV and a HMAC
You can encrypt in php like this

$key = substr('encyptionsec123342',0,32) function encrypt ($message, $method, $secret, &$hmac) { $iv = substr(bin2hex(openssl_random_pseudo_bytes(16)),0,16); $encrypted = base64_encode($iv) . openssl_encrypt($message, $method, $secret, 0, $iv); $hmac = hash_hmac('md5', $encrypted, $secret); return $encrypted; } function decrypt ($encrypted, $method, $secret, $hmac) { if (hash_hmac('md5', $encrypted, $secret) == $hmac) { $iv = base64_decode(substr($encrypted, 0, 24)); return openssl_decrypt(substr($encrypted, 24), $method, $secret, 0, $iv); } } function encryptWithTSValidation ($message, $method, $secret, &$hmac) { date_default_timezone_set('UTC'); $message = substr(date('c'),0,19) . "$message"; return encrypt($message, $method, $secret, $hmac); } function decryptWithTSValidation ($encrypted, $method, $secret, $hmac, $intervalThreshold) { $decrypted = decrypt($encrypted, $method, $secret, $hmac); $now = new DateTime(); $msgDate = new DateTime(str_replace("T"," ",substr($decrypted,0,19))); if (($now->getTimestamp() - $msgDate->getTimestamp()) <= $intervalThreshold) { return substr($decrypted,19); } } 

This is a secure AES-256-CBC method and with HMAC to stop man in the middle attacks.
Node.js

var secret = "encyptionsec123342"; secret = secret.substr(0, 32); var method = 'AES-256-CBC'; var encrypt = function(message, method, secret, hmac) { var iv = crypto.randomBytes(16).toString('hex').substr(0, 16); var encryptor = crypto.createCipheriv(method, secret, iv); var encrypted = new Buffer.alloc(iv).toString('base64') + encryptor.update(message, 'utf8', 'base64') + encryptor.final('base64'); hmac = crypto.createHmac('md5', secret).update(encrypted).digest('hex'); return encrypted; }; var decrypt = function(encrypted, method, secret, hmac) { if (crypto.createHmac('md5', secret).update(encrypted).digest('hex') == hmac) { var iv = new Buffer.from(encrypted.substr(0, 24), 'base64').toString(); var decryptor = crypto.createDecipheriv(method, secret, iv); return decryptor.update(encrypted.substr(24), 'base64', 'utf8') + decryptor.final('utf8'); } }; var encryptWithTSValidation = function(message, method, secret, hmac) { var messageTS = new Date().toISOString().substr(0, 19) + message; return encrypt(messageTS, method, secret, hmac); } var decryptWithTSValidation = function(encrypted, method, secret, hmac, intervalThreshold) { var decrypted = decrypt(encrypted, method, secret, hmac); var now = new Date(); var year = parseInt(decrypted.substr(0, 4)), month = parseInt(decrypted.substr(5, 2)) - 1, day = parseInt(decrypted.substr(8, 2)), hour = parseInt(decrypted.substr(11, 2)), minute = parseInt(decrypted.substr(14, 2)), second = parseInt(decrypted.substr(17, 2)); var msgDate = new Date(Date.UTC(year, month, day, hour, minute, second)) if (Math.round((now - msgDate) / 1000) <= intervalThreshold) { return decrypted.substr(19); } } 

To perform encryption and decryption in php,

$encrypted = encryptWithTSValidation($recipent, $method, $key, $hmac); $decrypted = decryptWithTSValidation($encrypted,$method,$key, $hmac, 60*60*12)//this is 12 hours 

to generate a hmac, you can use simple md5 hashing

$hmac = hash_hmac('md5', $recipent, $key); 

and in node.js

var decrypted = decryptWithTSValidation(encString, method, secret, hmac, 60 * 60); var encrypted = decryptWithTSValidation(string, method, secret, hmac); 

NOTE: Make sure to make a unique key that is of 32 bit and is same while encryption and decryption in nodejs and php. Also keep it safe and never store it in a database.
Code Reference : Encrypt string in PHP and decrypt in Node.js

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

7 Comments

@AppelFlap Happy to help
What is the MitM attack here? If you want to suggest a better alternative suggest Authenticated Encryption as AES-GCM that is included in TLS 1.4
@kelalaka nodejs is used for “real-time” applications, it may be possible the user is using it in web sockets etc.
@kelalaka no i mean the op might be using it in direct communications like webscokets maybe that's why he's integrating node.js and php like i once did
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.