Search code examples
phphashcryptographysha512php-openssl

openssl_encrypt returning empty string


I am trying to create a UUID on my server, and for some reason openssl_enrypt is initializing an empty string. This would be a different conversation if it was returning false, but it's not, it's returning a string, just one that's empty.

Here is all of my code I'm using to build the encrypted string I want:

$key = hash_hmac("sha512", "You can decrypt this all day long, won't get you closer to the truth", "myKey");
$iv = openssl_random_pseudo_bytes(16);
$adminVal = filter_var($userData['is_admin'], FILTER_VALIDATE_BOOLEAN);
$userName = $userData["name"];
$dataEncrypt = $adminVal.$userName;
$encrypted = openssl_encrypt($dataEncrypt, "AES-256-XTS", $key, 0, $iv);

I have var_dumped $key, $iv, and $dataEncrypt and they all return correct values.


Solution

  • @Fred-ii- You're absolutely right, thank you! I can't believe I didn't see that...I would love to give you the answer!

    As requested:

    It seems to be the method you're using AES-256-XTS. If you change that to aes128 or AES-128-CBC for example, you'll see a result. Consult the documentation http://php.net/manual/en/function.openssl-encrypt.php - There is no AES-256-XTS listed in the manual.

    Edit: I removed the bug report from a previous edit which I will investigate this further as to why this ended up producing an empty result.

    Since the (cipher) method does (in fact) exist when running a var_dump(openssl_get_cipher_methods());, it may also depend on openssl; as pulled/taken from a comment left in the bug report.

    I will update my answer if/once I can hopefully get results/an explanation as to why the OP's and my own tests came up as empty and to get more information from the OP.


    Edited:

    After doing more research, I stumbled upon this link and that code worked "right out of the box" using the "AES-256-XTS" cipher method (note; consult the commented line note in the source script near the end).

    In looking at that code and comparing it with the OP, I noticed that it was the data/message that required to be encrypted.

    • The message was hashed "as the key" which in turn made the string empty. Only hash the key and not both key and data/message, as you were trying to encrypt both an existing hashing method with the message and key "as the key".

    The resulting script came out being the following:

    Sidenote: The commented lines just below, also work with their respective parts; just don't use both at the same time.

    $plaintext = 'The secret message in plain text';
    $password = '3sc3RLrpd17';
    $key = substr(hash('sha256', $password, true), 0, 32);
    
    $iv = openssl_random_pseudo_bytes(16);
    $method = "aes-256-xts";
    $userName = "JOHN";
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
    // $encrypted = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
    
        echo "<br>";
        var_dump($iv);
        echo "<br>";
        var_dump($userName);
        echo "<br>";
        var_dump($encrypted);
        echo "<hr>";
    
    $decrypted = openssl_decrypt(base64_decode($encrypted), $method, $key, OPENSSL_RAW_DATA, $iv);
    // $decrypted = openssl_decrypt($encrypted, $method, $key, OPENSSL_RAW_DATA, $iv);
        echo 'decrypted to: ' . $decrypted . "\n\n";
    

    Special note: I also had some help in picking Jay Blanchard's brain and testing; two heads are often better than one, so Jay deserves credit for this also.

    NOTE: More than one source indicates it ("AES-256-XTS") is for file systems / disk encryption. You could say "AES-256-XTS and AES-128-XTS" methods really intended for file system encryption and therefore are not suitable for text.

    Source code pulled from this link:

    <?php
    
    $plaintext = 'My secret message 1234';
    $password = '3sc3RLrpd17';
    $method = 'aes-256-cbc'; // I replaced aes-256-cbc with aes-256-xts during testing
    
    // Must be exact 32 chars (256 bit)
    $password = substr(hash('sha256', $password, true), 0, 32);
    echo "Password:" . $password . "\n";
    
    // IV must be exact 16 chars (128 bit)
    $iv = chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0) . chr(0x0);
    
    // av3DYGLkwBsErphcyYp+imUW4QKs19hUnFyyYcXwURU=
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $password, OPENSSL_RAW_DATA, $iv));
    
    // My secret message 1234
    $decrypted = openssl_decrypt(base64_decode($encrypted), $method, $password, OPENSSL_RAW_DATA, $iv);
    
    echo 'plaintext=' . $plaintext . "\n";
    echo 'cipher=' . $method . "\n";
    echo 'encrypted to: ' . $encrypted . "\n";
    echo 'decrypted to: ' . $decrypted . "\n\n";