Encrypting a plain text file in C
I a开发者_运维技巧m 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.
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.
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.
You need the SSL development packages. (libssl-dev in Ubuntu). Depending on how you implement it, you will also need libcrypto-dev.
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.
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.
精彩评论