8

How do I encrypt data in PHP using openssl and decrypt in C++?

EDIT: I got it to work somewhat, but now I have an issue that it outputs more characters in the console for some reason.

php code

openssl_encrypt("testtest", "AES-256-CBC", "01234567890123456789012345678901", 0, "0123456789012345");

c++ code

int main() {
    /* A 256 bit key */
    unsigned char* key = (unsigned char*)"01234567890123456789012345678901";
    /* A 128 bit IV */
    unsigned char* iv = (unsigned char*)"0123456789012345";

    std::vector<byte> data = base64_decode("2fd9RV8QVVUAR2n5WLjiSA==");
    byte* ciphertext = new byte[data.size()];

    for (size_t i = 0; i < data.size(); i++)
    {
        ciphertext[i] = data.at(i);
    }

    byte decryptedtext[128];
    int decryptedtext_len;

    decryptedtext_len = decrypt(ciphertext, data.size(), key, iv, decryptedtext);

    std::cout << decryptedtext;

    return 0;
}

The decrypt function is from the OpenSSL wiki (link).

Base64_decode is from here

I get testtestŘŹ as output in the console instead of just testtest.

Aerd6154
  • 93
  • 8
  • This is most probably an encoding problem. Try the following: Output the cryptotext and pipe it through "xxd" (or a similar hexdump program). Then add the cryptotext to the c source using "\x12\x13\x57...." and so on. See if it works this way. – Ctx Dec 21 '19 at 11:31
  • you should transfer the data with an encoding like base64. Binary encoding is problematic. – kelalaka Dec 21 '19 at 13:44
  • @Ctx that didn't change anything – Aerd6154 Dec 21 '19 at 15:26
  • @kelalaka tried that, but its still not the same. – Aerd6154 Dec 21 '19 at 15:27
  • I don't know, but if you use a pointer type and then call `sizeof` on what is basically random data, then maybe C++ is not for you (and I'm not trying to be crude, C++ is definitely not something for me either). It's like handing Big Bertha to somebody who is prone to shooting himself in the foot. – Maarten Bodewes Dec 21 '19 at 15:55
  • 1
    PHP-code: (1) Key: Use a 32 byte key for AES-256-CBC. (2) IV: Use `hex2bin` and a hexadecimal string (your `0` is turned into an IV whose first byte is `0x30` and whose remaining bytes are `0x00`). (3) Options: Use `0` (instead of `OPENSSL_RAW_DATA`) to directly return the ciphertext Base64-encoded. C-code: (4) Use the high level (instead of the low level) OpenSSL functions (EVP-functions). [Here](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption#Decrypting_the_Message) is an example that can be adopted 1:1 (switch to `EVP_aes_128_cbc()` if AES-128-CBC is used). – Topaco Dec 21 '19 at 19:17
  • @Topaco why `0` has `0x30` in the first place? – kelalaka Dec 21 '19 at 19:20
  • 1
    @kelalaka - It's a guess I've confirmed by trial and error. I suspect that the _value_ `0` is converted to the _string_ `0` because [`openssl_encrypt`](https://www.php.net/manual/en/function.openssl-encrypt.php) expects the IV as _string_. The character `0` has the ASCII-value `0x30`. Since `openssl_encrypt` needs a 16 byte IV, PHP pads with `0`-bytes afterwards (which it always does when something is too short), so that the strange IV results. – Topaco Dec 21 '19 at 19:58
  • 1
    @Topaco I see, the danger of implicit conversion – kelalaka Dec 21 '19 at 19:59
  • @Topaco thanks so much for the help. I've got it working almost, I edited the post now with the new issue which is the 3 extra characters on the end. – Aerd6154 Dec 22 '19 at 10:09
  • 2
    Try setting the terminating `0`: `decryptedtext[decryptedtext_len] = 0;` – Topaco Dec 22 '19 at 10:25
  • @Topaco yep that fixed it, thanks. – Aerd6154 Dec 22 '19 at 10:39
  • @Topaco one more thing, when I try to cipher a file with file_get_contents, when it gets decrypted in c++ it returns only few characters or just a one. – Aerd6154 Dec 22 '19 at 11:08
  • [`file_get_contents`](https://www.php.net/manual/en/function.file-get-contents.php) isn't for _encryption_, it reads the contents of a file into a string. You are probably reading data and then using the wrong encoding. Try to Base64-encode the data on the PHP-side after reading it and Base64-decode it on the C++-side. If you get stuck, post a _new_ question, because without code it's hard to analyze a problem and it's actually a new question. – Topaco Dec 22 '19 at 11:53
  • Since this question is NOT about c, strongly suggest removing the 'c' tag – user3629249 Dec 23 '19 at 23:45

0 Answers0