1

私は現在、クラス用に SSL 暗号化 VFS ファイル システムを開発していますが、ファイルの暗号化に問題があります。彼らが私たちに提供した例では、入力ファイルのテキストが読み取られ、暗号化され、暗号化されたファイルとして出力に書き込まれる、入力と出力の 2 つのファイルが必要でした。ただし、割り当てのために、単一の入力ファイルを取得し、そのファイル自体を暗号化して、暗号化された出力を返さないようにする必要があります。

すべての暗号化されたテキストを取得してバッファに保存し、バッファに保存された暗号化されたテキストで入力ファイルを上書きしようとするこのコードを以下に記述しました。バッファーを入力ファイルに書き込む最後の for ループのコードでセグメンテーション違反が発生しています。count = 4 の場合、segfault が発生します。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;
}
4

1 に答える 1

1

取得する暗号化されたデータはバイナリ形式であり、NULL で終わる文字列ではありません。strlen() は使用できません。outlen に格納されている値を使用する必要があります。

于 2013-04-24T12:05:51.817 に答える