AES_cbc_encrypt

时间:2017-04-25 10:46:42

标签: c memory-management aes

我尝试使用 openssl 库中的 AES_cbc_encrypt 功能加密和解密密钥库。

我的内存分配存在问题,如果有人能以适当的方式给我一些建议,那就太好了。

目前我无法弄清楚如何执行此操作,以便在 AES_cbc_encrypt 被调用时分段错误

另一个问题是如何为C中的char表分配内存(干净的方式)。我想动态地这样做。此问题的代码位置标有 QUESTION 字符串。

unsigned char *input;
input = malloc(sizeof(unsigned char)*length);   
unsigned char input_question[length];

输出:

[enc_dec_keystore] length: 82    
[enc_dec_keystore] QUESTION #1: why sizeof(input) != sizeof(input_question)
[enc_dec_keystore] input size: 8
[enc_dec_keystore] input_question size: 82

为什么 sizeof(输入)不同。因为我以这种方式获得了指针的大小?我希望得到 82 ,因为 sizeof(unsigned char)应该是1,乘以82应该是82,对吗?

以下是我的程序中的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/sha.h>

#define DEBUG 1
#define KEYLEN 128

void print_data(const char *tittle, const void* data, int len)
{
    printf("%s : ",tittle);
    const unsigned char * p = (const unsigned char*)data;
    int i = 0;

    for (; i<len; ++i)
        printf("%02X ", *p++);

    printf("\n");
}

void PBKDF2_HMAC_SHA_512(const char *pass, const unsigned char *salt, int32_t iterations, uint32_t outputBytes, unsigned char *result) {
    if (DEBUG) {
        puts("[PBKDF2_HMAC_SHA_512] in");
    }    
    unsigned char digest[outputBytes];
    PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, strlen(salt), iterations, EVP_sha512(), outputBytes, digest);
    for (int i = 0; i < sizeof(digest); i++)
    {        
        result[i] = digest[i];
    };
    if (DEBUG) {
        puts("[PBKDF2_HMAC_SHA_512] out");  
    }    
}

int deriver_key(const char *pass, const char *salt, unsigned char *key) {
    if (DEBUG) {
        puts("[deriver_key] in");
    }
    /* allocate 16 bytes of memory for key (128 bits) */
    key = (unsigned char *) malloc(sizeof(unsigned char)*16);
    /* let's make 10 iteration for now */
    PBKDF2_HMAC_SHA_512(pass, salt, 10, KEYLEN/8, key);
    if (DEBUG) {
        printf("[deriver_key] key(string): %s\n", key);
        printf("[deriver_key] key(bytes): ");
        for(int i=0; i<KEYLEN/8; i++) {
            printf("%02x", key[i]);
        }
        printf("\n");
        puts("[deriver_key] out");
    }

    return 0;
}

int enc_dec_keystore(char *keystore, char *key) {   
    /* length of keystore */
    int length;
    /* if (length % AES_BLOCK_SIZE) !=0 -> fill to 16 bytes block */
    int pad_length;
    int pad_counter = 0;

    FILE *fp;
    fp = fopen(keystore, "rb");
    fseek(fp, 0L, SEEK_END);
    length = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    if (DEBUG) {
        printf("[enc_dec_keystore] keystore length: %i\n", length); 
    }

    /* check if input fills blocks correctly */
    pad_length = length;        
    while(pad_length % AES_BLOCK_SIZE !=0) {
        pad_length++;
        pad_counter++;
    }
    if (DEBUG) {
        printf("[enc_dec_keystore] pad_length: %i\n", pad_length);
    }

    /* IV - fill with 0 for now */
    unsigned char iv[AES_BLOCK_SIZE];
    memset(iv, 0x00, AES_BLOCK_SIZE);

    unsigned char *input;
    input = malloc(sizeof(unsigned char)*length);   
    unsigned char input_question[length];
    if (DEBUG) {
        printf("\n[enc_dec_keystore] QUESTION #1: why sizeof(input) != sizeof(input_question)\n");
        printf("[enc_dec_keystore] input size: %lu\n", sizeof(input));
        printf("[enc_dec_keystore] input_question size: %lu\n\n", sizeof(input_question));
    }

    /* read data from file */
    int ret = 0;
    ret = fread(input, 1, length, fp);
    if (ret == 0) {
        puts("[enc_dec_keystore] file doesn't exist");
    }

    /* close the file after read */
    fclose(fp);

    if (DEBUG) {
        printf("[enc_dec_keystore] sizeof input: %lu, input length: %lu\n", sizeof(input), strlen(input));  
        printf("[enc_dec_keystore] input data: \n%s\n", input);
    }       
    /* allocate memory for aes's output */
    unsigned char *enc_out;
    enc_out = malloc(sizeof(unsigned char)*pad_length);
    unsigned char enc_out_question[pad_length];
    /* padding with 0 */
    memset(enc_out, 0, sizeof(enc_out));    
    if (DEBUG) {
        printf("\n[enc_dec_keystore] QUESTION #2: (again) why sizeof(enc_out) != sizeof(enc_out_question)\n");
        printf("[enc_dec_keystore] enc_out size: %lu\n", sizeof(enc_out));
        printf("[enc_dec_keystore] enc_out_question size: %lu\n\n", sizeof(enc_out_question));
    }

    /* AES-128 bit CBC Encryption */
    /* set up a key */
    /*
    unsigned char key_again[KEYLEN/8];
    for (int i=0; i<KEYLEN/8; i++) {
        key_again[i] = key[i];
    }
    */
    AES_KEY enc_key;
    AES_set_encrypt_key(key, 128, &enc_key);
    /* encrypt input data to enc_out */
    AES_cbc_encrypt(input, enc_out, sizeof(input), &enc_key, iv, AES_ENCRYPT);
    if (DEBUG) {
        printf("[enc_dec_keystore] encryption - aes output(string): %s\n", enc_out);
        printf("[enc_dec_keystore] encryption - aes output(bytes): ");
        for(int i=0; i<pad_length; i++) {
            printf("%02x", enc_out[i]);
        }
        printf("\n");       
    }

    /* AES-128 bit CBC Decryption */
    /*
    AES_KEY dec_key;
    AES_set_encrypt_key(key, 128, &enc_key);
    memset(iv, 0x00, AES_BLOCK_SIZE);   
    unsigned char *enc_out;
    enc_out = malloc(sizeof(unsigned char)*pad_length);
    AES_cbc_encrypt(enc_out, dec_out, sizeof(enc_out), &enc_key, iv, AES_ENCRYPT);
    if (DEBUG) {
        printf("[enc_dec_keystore] decryption - aes output(string): %s\n", enc_out);
        printf("[enc_dec_keystore] decryption - aes output(bytes): ");
        for(int i=0; i<pad_length; i++) {
            printf("%02x", enc_out[i]);
        }
        printf("\n");
        puts("[enc_dec_keystore] out");     
    }
    */

    return 0;
}

int main(int argc, char **argv) {   
    char *user = "user";    
    char *key_id = "key1";  
    const char *pass = "temppass";  
    const char *salt = "tempsalt";
    char *keystore = "keystore";    

    /* Deriver key from password and salt */
    unsigned char *key;
    if (deriver_key(pass, salt, key) != 0) {
        puts("[main] error with key derivery");
    }   

    /* Encrypt and decrypt keystore (for tests) */  
    if (enc_dec_keystore(keystore, key) != 0) {
        puts("[main] error with encrypting/decrypting keystore");
    }


    return 0;
}

密钥库文件包含:

keyid1:01020304050607080900010203040506:
keyid2:06050403020100090807060504030201:

1 个答案:

答案 0 :(得分:1)

为什么sizeof(输入)不是82,因为sizeof只返回指针变量的大小,它不返回动态分配数据的大小。 PBKDF2_HMAC_SHA_512返回二进制密钥,该密钥可能不会被&#39; \ 0&#39;分隔,这可能会在您打印密钥时导致段错误