简体   繁体   中英

Encrypt in PHP, decrypt in C

I'd like to encrypt a string in PHP and then decrypt it in C. I'm stuck on the decryption part.

(PHP) I first encrypt the string:

function encrypt($plaintext, $key) {
    $iv = 'aaaaaaaaaaaaaaaa';

    $ciphertext = openssl_encrypt($plaintext, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv);

    return $ciphertext;
}

echo encrypt('This is a test', 'test');
// output: 7q�7h_��8� ��L

(C) Then I want to decrypt it, I use tiny-AES-c library for the functions:

int test_decrypt_cbc(void) {
    uint8_t key[] = "test";
    uint8_t iv[]  = "aaaaaaaaaaaaaaaa";
    uint8_t str[] = "7q�7h_��8� ��L";

    printf("%s", str);

    printf("\n Decrypted buffer\n");

    struct AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);
    AES_CBC_decrypt_buffer(&ctx, str, sizeof(str));
    
    printf("%s", str);

    printf("\n");
    return 1;
}

This outputs:

7q�7h_��8� ��L
 Decrypted buffer
?L??Ɵ??m??Dˍ?'?&??c?W

It should instead output "This is a test".

How can I fix this?

  • In the PHP code, AES-256 is used. tiny-AES-c only supports AES-128 by default. In order for AES-256 to be supported, the corresponding constant must be defined in aes.h, ie the line //#define AES256 1 must be commented in, here .

  • PHP uses PKCS7 padding by default. The padding should be removed in the C code.

  • PHP implicitly pads too short keys with zero values to the specified length. Since AES-256-CBC was specified in the PHP code, the key test is extended as follows:

     test\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0

    In the C code this extended key must be used (see also the comment of @r3mainer).

  • For the transfer of the ciphertext between the two codes a suitable encoding must be used, eg Base64 or hexadecimal (see also the comment of @Ôrel). For the latter, bin2hex can be applied to the ciphertext in the PHP code. An example of a hex decoding in C can be found here .

  • A possible C-implementation is:

     // Pad the key with zero values uint8_t key[] = "test\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; uint8_t iv[] = "aaaaaaaaaaaaaaaa"; uint8_t ciphertextHex[] = "3771e837685ff5d4173801900de6e14c"; // Hex decode (eg https://stackoverflow.com/a/3409211/9014097) uint8_t ciphertext[sizeof(ciphertextHex) / 2], * pos = ciphertextHex; for (size_t count = 0; count < sizeof ciphertext / sizeof * ciphertext; count++) { sscanf((const char*)pos, "%2hhx", &ciphertext[count]); pos += 2; } // Decrypt struct AES_ctx ctx; AES_init_ctx_iv(&ctx, key, iv); AES_CBC_decrypt_buffer(&ctx, ciphertext, sizeof(ciphertext)); // Remove the PKCS7 padding uint8_t ciphertextLength = sizeof(ciphertext); uint8_t numberOfPaddingBytes = ciphertext[ciphertextLength - 1]; ciphertext[ciphertextLength - numberOfPaddingBytes] = 0; printf("%s", ciphertext);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM