Created
October 17, 2011 16:23
-
-
Save mythosil/1292999 to your computer and use it in GitHub Desktop.
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 <stdlib.h> | |
#include <string.h> | |
#include <openssl/evp.h> | |
char *encrypt(const char *data, const char *key, const char *iv, int *length) | |
{ | |
int key_length, iv_length, data_length; | |
key_length = strlen(key); | |
iv_length = strlen(iv); | |
data_length = strlen(data); | |
const EVP_CIPHER *cipher; | |
int cipher_key_length, cipher_iv_length; | |
cipher = EVP_aes_128_cbc(); | |
cipher_key_length = EVP_CIPHER_key_length(cipher); | |
cipher_iv_length = EVP_CIPHER_iv_length(cipher); | |
if (key_length != cipher_key_length || iv_length != cipher_iv_length) { | |
*length = 0; | |
return NULL; | |
} | |
EVP_CIPHER_CTX ctx; | |
int i, cipher_length, final_length; | |
unsigned char *ciphertext; | |
EVP_CIPHER_CTX_init(&ctx); | |
EVP_EncryptInit_ex(&ctx, cipher, NULL, (unsigned char *)key, (unsigned char *)iv); | |
cipher_length = data_length + EVP_MAX_BLOCK_LENGTH; | |
ciphertext = (unsigned char *)malloc(cipher_length); | |
EVP_EncryptUpdate(&ctx, ciphertext, &cipher_length, (unsigned char *)data, data_length); | |
EVP_EncryptFinal_ex(&ctx, ciphertext + cipher_length, &final_length); | |
/* | |
for (i = 0; i < cipher_length + final_length; i++) | |
printf("%02x", ciphertext[i]); | |
printf("\n"); | |
*/ | |
EVP_CIPHER_CTX_cleanup(&ctx); | |
*length = cipher_length + final_length; | |
return ciphertext; | |
} | |
char *decrypt(const char *data, int data_length, const char *key, const char *iv) | |
{ | |
int key_length, iv_length; | |
key_length = strlen(key); | |
iv_length = strlen(iv); | |
const EVP_CIPHER *cipher; | |
int cipher_key_length, cipher_iv_length; | |
cipher = EVP_aes_128_cbc(); | |
cipher_key_length = EVP_CIPHER_key_length(cipher); | |
cipher_iv_length = EVP_CIPHER_iv_length(cipher); | |
if (key_length != cipher_key_length || iv_length != cipher_iv_length) { | |
return NULL; | |
} | |
const char *p; | |
char *datax; | |
int i, datax_length; | |
datax = (char *)malloc(data_length); | |
memcpy(datax, data, data_length); | |
datax_length = data_length; | |
/* | |
for (p = data, i = 0; *p != '\0'; p += 2, i++) { | |
char buf[3]; | |
buf[0] = *p; | |
buf[1] = *(p+1); | |
buf[2] = '\0'; | |
datax[i] = strtol(buf, NULL, 16); | |
} | |
datax_length = i; | |
*/ | |
EVP_CIPHER_CTX ctx; | |
EVP_CIPHER_CTX_init(&ctx); | |
EVP_DecryptInit_ex(&ctx, cipher, NULL, (unsigned char *)key, (unsigned char *)iv); | |
int plain_length, final_length; | |
unsigned char *plaintext; | |
plain_length = datax_length; | |
plaintext = (unsigned char *)malloc(plain_length + 1); | |
EVP_DecryptUpdate(&ctx, plaintext, &plain_length, (unsigned char *)datax, datax_length); | |
EVP_DecryptFinal_ex(&ctx, plaintext + plain_length, &final_length); | |
plaintext[plain_length + final_length] = '\0'; | |
//printf("%s\n", plaintext); | |
free(datax); | |
EVP_CIPHER_CTX_cleanup(&ctx); | |
return plaintext; | |
} | |
int main(int argc, const char* argv[]) | |
{ | |
if (argc <= 3) { | |
fprintf(stderr, "Usage: %s <key> <iv> <data>\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
const char *key, *iv, *data; | |
char *encrypted, *decrypted; | |
int enc_length, i; | |
key = argv[1]; | |
iv = argv[2]; | |
data = argv[3]; | |
encrypted = encrypt(data, key, iv, &enc_length); | |
for (i = 0; i < enc_length; i++) | |
printf("%02x", (unsigned char)encrypted[i]); | |
printf("\n"); | |
decrypted = decrypt(encrypted, enc_length, key, iv); | |
printf("%s\n", decrypted); | |
free(encrypted); | |
free(decrypted); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment