2013-04-23 97 views
1

我目前正在爲我的班級開發一個SSL加密的VFS文件系統,並且在文件加密時遇到了一些麻煩。他們爲我們提供的示例需要兩個文件,即輸入和輸出,其中輸入文件文本被讀取,加密並作爲加密文件寫入輸出。但是,對於分配,我們需要採用單個輸入文件並對該文件本身進行加密,而不會返回加密輸出。OpenSSL文件加密問題

我已經寫下了下面的代碼,試圖將所有加密的文本存儲到緩衝區中,然後用保存在緩衝區中的加密文本覆蓋輸入文件。我在最後一個for循環的代碼中獲取了一段segfault,將緩衝區寫入輸入文件。當count = 4時發生段錯誤; z等於3.我認爲這是發生的,因爲我以某種方式存儲了錯誤的數據,但我似乎無法在這裏指出確切的問題。

任何幫助,將不勝感激。

這是代碼。

#define BLOCKSIZE 1024 
#define FAILURE 0 
#define SUCCESS 1 

extern int do_crypt(FILE* in, int action, char* key_str){ 
    /* Local Vars */ 

    /* Buffers */ 
    unsigned char inbuf[BLOCKSIZE]; 
    int inlen; 
    int z; 
    int count = 0; 
    /* Allow enough space in output buffer for additional cipher block */ 
    unsigned char outbuf[BLOCKSIZE + EVP_MAX_BLOCK_LENGTH]; 
    unsigned char **storebuf = malloc((BLOCKSIZE + EVP_MAX_BLOCK_LENGTH)*20); 

    int outlen; 
    //int writelen; 

    /* OpenSSL libcrypto vars */ 
    EVP_CIPHER_CTX ctx; 
    unsigned char key[32]; 
    unsigned char iv[32]; 
    int nrounds = 5; 

    /* tmp vars */ 
    int i; 

    /* Setup Encryption Key and Cipher Engine if in cipher mode */ 
    if(action >= 0){ 
    if(!key_str){ 
     /* Error */ 
     fprintf(stderr, "Key_str must not be NULL\n"); 
     return 0; 
    } 
    /* Build Key from String */ 
    i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, 
       (unsigned char*)key_str, strlen(key_str), nrounds, key, iv); 
    if (i != 32) { 
     /* Error */ 
     fprintf(stderr, "Key size is %d bits - should be 256 bits\n", i*8); 
     return 0; 
    } 
    /* Init Engine */ 
    EVP_CIPHER_CTX_init(&ctx); 
    EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv, action); 
    }  

    /* Loop through Input File*/ 
    for(;;){ 
    /* Read Block into inbuf */ 

    inlen = fread(inbuf, sizeof(*inbuf), BLOCKSIZE, in); 
    if(inlen <= 0){ 
     /* EOF -> Break Loop */ 
     break; 
    } 

    /* If in encrypt/decrypt mode, perform cipher transform on block */ 
    if(action >= 0){ 
     /*set up ctx with passed params */ 
     if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) 
     { 
      /* Error */ 
      EVP_CIPHER_CTX_cleanup(&ctx); 
      return 0; 
     } 
    } 
    /* If in pass-through mode. copy block as is */ 
    else{ 
     memcpy(outbuf, inbuf, inlen); 
     outlen = inlen; 
    } 

    storebuf[count] = malloc(outlen*sizeof(*outbuf)); 
    memcpy(storebuf[count], outbuf, outlen); 
    /* Write Block */ 
    //writelen = fwrite(outbuf, sizeof(*outbuf), outlen, out);//THIS LINE 
    if(storebuf[count] == NULL){ 
     /* Error */ 
     perror("malloc error"); 
     EVP_CIPHER_CTX_cleanup(&ctx); 
     return 0; 
    } 
    count++; 

    } 
    count++; 
    /* If in cipher mode, handle necessary padding */ 
    if(action >= 0){ 
    /* Handle remaining cipher block + padding */ 
    if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) 
     { 
     /* Error */ 
     EVP_CIPHER_CTX_cleanup(&ctx); 
     return 0; 
     } 
    /* Write remaining cipher block + padding*/ 
    //fwrite(outbuf, sizeof(*inbuf), outlen, out); 
    storebuf[count] = malloc(outlen*sizeof(*inbuf)); 
    memcpy(storebuf[count], outbuf, inlen); 
    EVP_CIPHER_CTX_cleanup(&ctx); 
    } 
    printf("%d, %s", count, storebuf[count]); 

    rewind(in); 
    for(z = 0; z < count-1; z++){ 
     fwrite(storebuf[z], sizeof(*storebuf), strlen((char*)storebuf[z]), in); 

    } 
    /* Success */ 
    return 1; 
} 
+0

一個非常一般的評論:通常你不會把*緩衝區寫入*輸入文件*。 – 2013-04-24 19:23:44

+0

它更像是一個通過該函數編輯的文件 – rozay 2013-04-25 01:09:18

回答

1

你得到的ecnrypted數據是二進制形式,不是以NULL結尾的字符串。你不能使用strlen(),你需要使用存儲在outlen中的值。