Error1f1f
Error1f1f

Reputation: 539

Encrypting a plain text file in C

I am currently writing a linux application in C that reads from a configuration file. This configuration file contains some data that I would like to encrypt so it is not plain text. I have spent hours researching this and have not found a viable solution. Since the application will need to read from the configuration I will need to be able to encrypt it and decrypt it on the fly. So far from research I really like openSSL crypto library. I know from the command line you can do:

openssl enc -aes-256-cbc -salt -in file.txt -out file.enc

If anyone can provide an example of how I can do this in C, it would be most appreciated.

Upvotes: 4

Views: 5067

Answers (5)

Liberius
Liberius

Reputation: 148

Why not do your own? Read enough bytes from dev/random (your key) and XOR the configuration file with it. To decrypt, XOR again with the same key. This is simple,fast,and secure. No complicated libraries needed.

Upvotes: 0

Nielsson
Nielsson

Reputation: 86

You should have a look at the O'Reilly-Book. There are a couple of examples on how to encrypt things. Unfortunately the most are for Network-Encryption.

I found an example in the book, but didnt test it:

#include <openssl/evp.h>

int main(int argc,  char *argv[])
{
    EVP_CIPHER_CTX  ctx;
    char            key[EVP_MAX_KEY_LENGTH];
    char            iv[EVP_MAX_IV_LENGTH];
    char            *ct, *out;
    char            final[EVP_MAX_BLOCK_LENGTH];
    char            str[] = "123456789abcdef";
    int             i;
    if (!seed_prng())
    {
    printf("Fatal Error!  Unable to seed the PRNG!\n");
    abort();
    }
    select_random_key(key, EVP_MAX_KEY_LENGTH);
    select_random_iv(iv, EVP_MAX_IV_LENGTH);
    EVP_EncryptInit(&ctx, EVP_bf_cbc(), key, iv);
    ct = encrypt_example(&ctx, str, strlen(str), &i);
    printf("Ciphertext is %d bytes.\n", i);
    EVP_DecryptInit(&ctx, EVP_bf_cbc(), key, iv);
    out = decrypt_example(&ctx, ct, 8);
    printf("Decrypted: >>%s<<\n", out);
    out = decrypt_example(&ctx, ct + 8, 8);
    printf("Decrypted: >>%s<<\n", out);
    if (!EVP_DecryptFinal(&ctx, final, &i))
    {
    printf("Padding incorrect.\n");
    abort();
    }
    final[i] = 0;
    printf("Decrypted: >>%s<<\n", final);
}

char *encrypt_example(EVP_CIPHER_CTX *ctx, char *data, int inl, int *rb) 
{
    char *ret;
    int i, tmp, ol;
    ol = 0;
    ret = (char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx));
    for (i = 0; i < inl / 100; i++)
    {
    EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], 100);
    ol += tmp;
    }
    if (inl % 100)
    {
    EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], inl%100);
    ol += tmp;
    }
    EVP_EncryptFinal(ctx, &ret[ol], &tmp);
    *rb = ol + tmp;
    return ret;
}

char *decrypt_example(EVP_CIPHER_CTX *ctx, char *ct, int inl)
{
    /* We're going to null-terminate the plaintext under the assumption it's
     * non-null terminated ASCII text. The null can be ignored otherwise.
     */
    char *pt = (char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx) + 1);
    int ol;
    EVP_DecryptUpdate(ctx, pt, &ol, ct, inl);
    if (!ol) /* there's no block to decrypt */
    {
    free(pt);
    return NULL;
    }
    pt[ol] = 0;
    return pt;
}

Hope this will help you.

Upvotes: 4

mrduclaw
mrduclaw

Reputation: 4035

I'm not a huge O'Reilly fan, but I found this book to be very helpful when starting this type of thing for the first time.

Upvotes: 0

OneOfOne
OneOfOne

Reputation: 99195

Check this answer and check this article.

You can replace EVP_bf_cbc() with EVP_aes_128_cbc() EVP_aes_192_cbc() or EVP_aes_256_cbc() depending on what you need.

Upvotes: 1

Andrew Sledge
Andrew Sledge

Reputation: 10351

You need the SSL development packages. (libssl-dev in Ubuntu). Depending on how you implement it, you will also need libcrypto-dev.

Upvotes: 0

Related Questions