3

I am encrypting a password in PHP, and want to decrypt it on a different box. I am having no luck and I would prefer to be able to decrypt it right from bash and echo it. Below is a snippet of a test in PHP.

$textToEncrypt    = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  
$secretHash       = "Testkey";

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash);

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);

//Result
echo "Encrypted: $encryptedMessage <br>Decrypted: $decryptedMessage";

I have tried numerous methods to decrypt it on Ubuntu, even storing the data to a file and outputting it to a file. Command tried was:

openssl aes-256-cbc -a -d -k Testkey -in foo.txt -out secrets.txt

Where foo.txt is the value returned from the PHP encryption, and secrets.txt is the output. How can I do this?

5
  • 1
    Not using an initialization vector (iv) is not a good idea; maybe it's not working because it's afraid. Commented Jan 17, 2016 at 5:28
  • What would my php look like if I added that, I think its how its formatted thou between php and bash. Commented Jan 17, 2016 at 5:47
  • -k Testkey will derive a key from the password Testkey, while in php openssl_encrypt(...,..., ' Testkey') will use Testkey directly as the key. Is it really necessary to use the openssl command line tool in this way (i.e. a) at all b) directly, without another program/script inbetween)? Commented Jan 17, 2016 at 6:47
  • I don't necessarily need to run it directly in the command line, my hope is to read this key from my database and decrypt it through a bash script, thus whatever tool is needed to do so, I will be happy to oblige. I just figured a command through shell would be easy, but I was wrong. If any other tools will do the same, let me know! Commented Jan 17, 2016 at 6:59
  • a) Could that command line tool also be a php script? Possibly with a #!/bin/php shebang? b) You don't care about the file format as long as it's working and not terribly bad? Commented Jan 17, 2016 at 7:16

2 Answers 2

3

It bears repeating, as in the comments, that encryption without an IV is dangerous. In fact, the current version of PHP will issue a warning about it. IVs can be randomly generated using the openssl_random_pseudo_bytes() function, and transmitted in the clear along with the encrypted text. They don't have to be secret, the important thing is not to reuse the same key and IV combination, and have a random IV.

So, with that out of the way, if you take a look at the source for the function, it's not passing the password argument as a passphrase, but rather as the key. So for using openssl on the command line, it needs to be in hex and passed to the -K option, not the -k option. But then, you'll get an error back saying "iv undefined" so your PHP needs to be adjusted to include one:

<?php
$textToEncrypt    = "My super secret information.\n";
$encryptionMethod = "AES-256-CBC";  
$key              = "Testkey";
$iv               = openssl_random_pseudo_bytes(
                        openssl_cipher_iv_length($encryptionMethod)
                    );

$keyHex           = bin2hex($key);
$ivHex            = bin2hex($iv);

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $key, 0, $iv);

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $key, 0, $iv);

//Result
printf(
    "Decrypted message: %s\n\nkeyHex=%s\nivHex=%s\nencryptedMessage=%s\n",
    $decryptedMessage,
    escapeshellarg($keyHex),
    escapeshellarg($ivHex),
    escapeshellarg($encryptedMessage)
);

Once you have these details, you can decrypt from command line (re-using PHP variable names here):

echo -n "$encryptedMessage" | openssl aes-256-cbc -d -a -A -K "$keyHex" -iv "$ivHex"
Sign up to request clarification or add additional context in comments.

3 Comments

I've tried this code as is, however on the linux side im getting an openssl error "bad decrypt" due to "wrong final block length". command: echo -n "o69dxUStEeJffwdvfiTjt0vOliLcNXZNbRrH18JbyRU=" | openssl aes-256-cbc -d -a -K "546573746b6579" -iv "34746f696a3335756e766f75716f7b32"
Yeah I am also try this solution and got the same error message like @QuickPrototype
@QuickPrototype fixed up for 2019. Better late than never, right?
0

The other way around

#!/bin/bash
#  create in bash keys
echo "generating private key"
openssl genrsa -out privkey.pem 2048
echo "signing private key"
openssl req -new -key privkey.pem -out certreq.csr -subj "/C=RO/ST=AB L=AB/O=None/OU=Department/CN=someweb.com"

echo "create a sign request"
openssl x509 -req -in certreq.csr -signkey privkey.pem -out newcert.pem
# end-of-bash-script
cp ./privkey.pem /path/to/apache/root/<some>

Encrypt some json file

openssl smime -encrypt -aes256 -in ./json.txt -binary -outform DER -out ./json.xxx newcert.pem
# test decrypt here in bash
# openssl smime -decrypt -in json.xxx -inform DER -inkey privkey.pem -out json.dec

Post it as binary to php

curl --request POST --data-binary @./json.xxx http://localhost/<some/>json.php

Then json.php script @ apache root

<?php

    $rkey = file_get_contents("/var/www/html/privkey.pem");
    $pkey = file_get_contents("/var/www/html/newcert.pem");
    $data = file_get_contents("php://input");
    $fenc = tempnam("", "enc"); 
    $fdec = tempnam("", "dec");
    file_put_contents($fenc,$data);
    // openssl_pkcs7_decrypt ($fenc , $fdec , $pkey, $rkey ); unable to coerce parameter 3 to x509 cert 
    system("openssl smime -decrypt -in ${fenc} -inform DER -inkey privkey.pem -out ${fdec}");
    echo  file_get_contents($fdec);
?>

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.