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.