Last active
July 4, 2023 16:26
-
-
Save giavac/aaa5dff3667264954dcb40a2088e44e1 to your computer and use it in GitHub Desktop.
Decodes from base64, decrypts with key, tag and iv, then decompresses
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <openssl/evp.h> | |
#include <openssl/rand.h> | |
#include <openssl/bio.h> | |
#include <openssl/buffer.h> | |
#include <zlib.h> | |
static char *base64_decode(const char *input, int length, int *output_length) { | |
BIO *bio, *b64; | |
int decode_size = length * 3 / 4; | |
char *buffer = malloc(decode_size); | |
bio = BIO_new_mem_buf(input, length); | |
b64 = BIO_new(BIO_f_base64()); | |
bio = BIO_push(b64, bio); | |
// Ignore newlines - write everything in one line | |
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); | |
*output_length = BIO_read(bio, buffer, length); | |
BIO_free_all(bio); | |
return buffer; | |
} | |
static unsigned decrypt(unsigned char *key, unsigned char *iv, unsigned char *tag, unsigned char *input, unsigned int input_len, unsigned char *plaintext) | |
{ | |
EVP_CIPHER_CTX *ctx; | |
unsigned int len = 0; | |
unsigned int plaintext_len = 0; | |
int ret = 0; | |
OpenSSL_add_all_algorithms(); | |
ctx = EVP_CIPHER_CTX_new(); | |
EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, key, iv); | |
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag); | |
EVP_DecryptUpdate(ctx, plaintext, &len, input, input_len); | |
plaintext_len = len; | |
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len); | |
if(ret > 0) { | |
/* Success */ | |
plaintext_len += len; | |
} | |
printf("plaintext len: %d\n", plaintext_len); | |
EVP_CIPHER_CTX_free(ctx); | |
return plaintext_len; | |
} | |
int main(int argc, char *argv[]) { | |
if (argc < 5) { | |
printf("Usage (all inputs base64 encoded): %s <encrypted> <tag> <iv> <key>\n", argv[0]); | |
return 1; | |
} | |
const char *encrypted_payload = argv[1]; | |
const char *tag = argv[2]; | |
const char *iv = argv[3]; | |
const char *key = argv[4]; | |
int len; | |
unsigned char plaintext[10240]; | |
int plaintext_len; | |
int ret; | |
/* payload */ | |
int encrypted_payload_len = strlen((char *)encrypted_payload); | |
printf("Encrypted len: %d\n", encrypted_payload_len); | |
int decoded_payload_len = 0; | |
unsigned char *decoded_payload = base64_decode((unsigned char*)encrypted_payload, encrypted_payload_len, &decoded_payload_len); | |
/* tag */ | |
int tag_len = strlen((char *)tag); | |
printf("Encoded tag len: %d\n", tag_len); | |
int decoded_tag_len = 0; | |
unsigned char *decoded_tag = base64_decode((unsigned char *)tag, tag_len, &decoded_tag_len); | |
/* iv */ | |
int iv_len = strlen((char *)iv); | |
printf("Encoded iv len: %d\n", iv_len); | |
int decoded_iv_len = 0; | |
unsigned char *decoded_iv = base64_decode((unsigned char *)iv, iv_len, &decoded_iv_len); | |
/* key */ | |
int key_len = strlen((char *)key); | |
printf("Encoded key len: %d\n", key_len); | |
int decoded_key_len = 0; | |
unsigned char *decoded_key = base64_decode((unsigned char *)key, key_len, &decoded_key_len); | |
plaintext_len = decrypt(decoded_key, decoded_iv, decoded_tag, decoded_payload, decoded_payload_len, plaintext); | |
unsigned char uncompressed[10240]; | |
long unsigned int uncompressed_len = 10240; | |
int uncompress_result = uncompress(uncompressed, &uncompressed_len, plaintext, plaintext_len); | |
printf("uncompressed (%d, %ld): \n", uncompress_result, uncompressed_len); | |
for (int m=0; m < uncompressed_len; m++) { | |
printf("%c", uncompressed[m]); | |
} | |
printf("\ndone\n"); | |
free(decoded_tag); | |
free(decoded_payload); | |
free(decoded_iv); | |
free(decoded_key); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment