• XSS.stack #1 – первый литературный журнал от юзеров форума

Best methods to crypt files on C language use libraries or not?

Hi, I understand that you want to encrypt files using the OpenSSL library and the C programming language. Below, I show you a basic example of how to encrypt and decrypt a file using AES with a symmetric key. This example uses AES-256 in CBC mode and generates an output file with the encrypted content.

1. Make sure you have OpenSSL and the development libraries installed on your system.

C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

void handleErrors() {
    printf("Error.\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Usage: %s <encrypt/decrypt> <input_file> <output_file>", argv[0]);
        return 1;
    }

    int encrypt = strcmp(argv[1], "encrypt") == 0;
    int decrypt = strcmp(argv[1], "decrypt") == 0;

    if (!encrypt && !decrypt) {
        printf("The operation must be 'encrypt' or 'decrypt'.\n");
        return 1;
    }

    FILE *input_file = fopen(argv[2], "rb");
    if (!input_file) {
        printf("Unable to open input file.\n");
        return 1;
    }

    FILE *output_file = fopen(argv[3], "wb");
    if (!output_file) {
        printf("Unable to open output file.\n");
        return 1;
    }

    // Generate
    unsigned char key[AES_BLOCK_SIZE * 2]; // AES-256
    unsigned char iv[AES_BLOCK_SIZE];
    if (!RAND_bytes(key, sizeof(key)) || !RAND_bytes(iv, sizeof(iv))) {
        handleErrors();
    }


    if (encrypt) {
        fwrite(iv, sizeof(iv), 1, output_file);
    } else {
        fread(iv, sizeof(iv), 1, input_file);
    }


    AES_KEY aes_key;
    if (encrypt) {
        AES_set_encrypt_key(key, 256, &aes_key);
    } else {
        AES_set_decrypt_key(key, 256, &aes_key);
    }


    unsigned char in_buf[AES_BLOCK_SIZE], out_buf[AES_BLOCK_SIZE];
    int in_len, out_len;
    while ((in_len = fread(in_buf, 1, sizeof(in_buf), input_file)) > 0) {
        if (encrypt && in_len < sizeof(in_buf)) {
            int padding = sizeof(in_buf) - in_len;
            memset(in_buf + in_len, padding, padding);
        }

        AES_cbc_encrypt(in_buf, out_buf, sizeof(in_buf), &aes_key, iv, encrypt ? AES_ENCRYPT : AES_DECRYPT);
        out_len = in_len;

        if (!encrypt && out_len > 0 && out_buf[out_len - 1] <= AES_BLOCK_SIZE) {
            int padding = out_buf[out_len - 1];
            int valid_padding = 1;
            for (int i = 0; i < padding; i++) {
                if (out_buf[out_buf[out_len - 1 - i] != padding) {
                    valid_padding = 0;
                    break;
                }
            }

            if (valid_padding) {
                out_len -= padding;
            }
        }

        fwrite(out_buf, 1, out_len, output_file);
    }

    fclose(input_file);
    fclose(output_file);

    printf("file %s successful.\n", encrypt ? "encrypt" : "den encrypt");

    return 0

For asymmetric encryption, you can use RSA cryptography, which is one of the most popular ones. Below is an example of how to encrypt and decrypt a file using RSA and the OpenSSL library in C.

C:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

void handleErrors() {
    printf("Error in encryption or decryption process.\n");
    exit(1);
}

int main(int argc, char *argv[]) {
    if (argc != 5) {
        printf("Usage: %s <encrypt/decrypt> <input_file> <output_file> <key_file> <key_file>", argv[0]);
        return 1;
    }

    int encrypt = strcmp(argv[1], "encrypt") == 0;
    int decrypt = strcmp(argv[1], "decrypt") == 0;

    if (!encrypt && !decrypt) {
        printf("The operation must be 'encrypt' or 'decrypt'.\n");
        return 1;
    }

    FILE *input_file = fopen(argv[2], "rb");
    if (!input_file) {
        printf("Unable to open input file.\n");
        return 1;
    }

    FILE *output_file = fopen(argv[3], "wb");
    if (!output_file) {
        printf("Unable to open output file.\n");
        return 1;
    }

    FILE *key_file = fopen(argv[4], "r");
    if (!key_file) {
        printf("Unable to open key file.\n");
        return 1;
    }

    RSA *rsa = RSA_new();
    if (encrypt) {
        rsa = PEM_read_RSA_PUBKEY(key_file, &rsa, NULL, NULL);
    } else {
        rsa = PEM_read_RSAPrivateKey(key_file, &rsa, NULL, NULL);
    }

    if (!rsa) {
        printf("Error reading key %s.key", encrypt ? "public" : "private");
        return 1;
    }

    int rsa_size = RSA_size(rsa);
    int block_size = encrypt ? rsa_size - 11 : rsa_size;
    unsigned char in_buf[block_size], out_buf[rsa_size];
    int in_len, out_len;

    while ((in_len = fread(in_buf, 1, sizeof(in_buf), input_file)) > 0) {
        if (encrypt) {
            out_len = RSA_public_encrypt(in_len, in_buf, out_buf, rsa, RSA_PKCS1_PADDING);
        } else {
            out_len = RSA_private_decrypt(in_len, in_buf, out_buf, rsa, RSA_PKCS1_PADDING);
        }

        if (out_len == -1) {
            handleErrors();
        }

        fwrite(out_buf, 1, out_len, output_file);
    }

    RSA_free(rsa);
    fclose(key_file);
    fclose(input_file);
    fclose(output_file);

    printf("File %s successfully.\n", encrypt ? "encrypted" : "decrypted");

    return 0;
}


Compile the program using gcc:

terminal command - gcc -o rsa_file_encryption rsa_file_encryption.c -lcrypto

Generate an RSA key pair (private and public). Execute the following commands:

terminal command - openssl genrsa -out
 
And to use GnuPG (GPG) in a C program, you can use the GPGME (GnuPG Made Easy) library, which provides a high-level interface to interact with GnuPG. Below is an example of how to encrypt a file using GPGME in C language.

Before you start, make sure you have the GnuPG and GPGME libraries installed. On Debian-based systems, you can install them with:

C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpgme.h>

void check_gpgpg_error(gpgme_error_t err) {
    if (err) {
        fprintf(stderr, "GPG Error: %s\n", gpgme_strerror(err));
        exit(1);
    }
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Usage: %s <input_file> <output_file> <recipient_key_id>", argv[0]);
        return 1;
    }

    gpgme_error_t err;
    gpgme_ctx_t ctx;

    // Initialize GPGME
    gpgme_check_version(NULL);
    err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
    check_gpgpg_error(err);
    err = gpgme_new(&ctx);
    check_gpg_error(err);

    // Set the cipher to use OpenPGP and symmetric encryption
    err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
    check_gpg_error(err);

    // Import the recipient's public key
    gpgme_key_t recipient_key;
    err = gpgme_get_key(ctx, argv[3], &recipient_key, 0);
    check_gpgpg_error(err);

    // Set the recipient for encryption.
    err = gpgme_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
    check_gpgpg_error(err);
    err = gpgme_op_keylist_start(ctx, argv[3], 0);
    check_gpg_error(err);
    err = gpgme_op_keylist_next(ctx, &recipient_key);
    check_gpg_error(err);

    // Open the input and output files
    FILE *input_file = fopen(argv[1], "rb");
    if (!input_file) {
        printf("Unable to open input file.\n");
        return 1;
    }

    FILE *output_file = fopen(argv[2], "wb");
    if (!output_file) {
        printf("Unable to open output file.\n");
        return 1;
    }

    // Configure input and output encryption.
    gpgme_data_t input, output;
    err = gpgme_data_new_from_stream(&input, input_file);
    check_gpgpg_error(err);
    err = gpgme_data_new_from_stream(&output, output_file);
    check_gpg_error(err);

    // Encrypt the file
    gpgme_encrypt_result_result_t result;
    err = gpgme_op_encrypt(ctx, &recipient_key, 1, input, output);
    check_gpgpg_error(err);
    result = gpgme_op_encrypt_result(ctx);
    if (result->invalid_recipients) {
        fprintf(stderr, "Invalid recipient encountered:%sname",result->invalid_recipients->fpr);
        return 1;
}
err = gpgme_data_seek(output, 0, SEEK_SET);
check_gpg_error(err);
char buffer[4096];
ssize_t read_bytes;
while ((read_bytes = gpgme_data_read(output, buffer, sizeof(buffer))) > 0) {
    fwrite(buffer, 1, read_bytes, output_file);
}

// Flushes and closes resources.
gpgme_key_unref(recipient_key);
gpgme_data_release(input);
gpgme_data_release(output);
fclose(input_file);
fclose(output_file);
gpgme_release(ctx);

printf("File successfully encrypted.ctx");

return 0;
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх