【问题标题】:Encrypting a plain text file in C在 C 中加密纯文本文件
【发布时间】:2010-12-03 17:41:12
【问题描述】:

我目前正在用 C 语言编写一个从配置文件读取的 linux 应用程序。此配置文件包含一些我想加密的数据,因此它不是纯文本。我花了几个小时研究这个问题,但没有找到可行的解决方案。由于应用程序需要从配置中读取,我需要能够对其进行加密和即时解密。到目前为止,我真的很喜欢 openSSL 加密库。我从命令行知道你可以这样做:

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

如果有人可以提供我如何在 C 中执行此操作的示例,将不胜感激。

【问题讨论】:

  • 我希望您知道任何有权访问相关文件的人都可以读取密钥文件并使用它来解密文本文件。您要向谁隐藏文本文件?我怀疑您的安全模型已损坏。

标签: c linux cryptography encryption


【解决方案1】:

你应该看看O'Reilly-Book。有几个关于如何加密事物的例子。不幸的是,大多数用于网络加密。

我在书中找到了一个例子,但没有测试:

#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;
}

希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    检查此answer 并检查此article

    您可以根据需要将EVP_bf_cbc() 替换为EVP_aes_128_cbc() EVP_aes_192_cbc() or EVP_aes_256_cbc()

    【讨论】:

      【解决方案3】:

      您需要 SSL 开发包。 (Ubuntu 中的 libssl-dev)。根据你的实现方式,你还需要 libcrypto-dev。

      【讨论】:

        【解决方案4】:

        我不是 O'Reilly 的忠实粉丝,但我发现 this 这本书在第一次开始这类事情时非常有帮助。

        【讨论】:

          【解决方案5】:

          为什么不自己做呢?从 dev/random (您的密钥)中读取足够的字节,并用它对配置文件进行异或。要解密,请使用相同的密钥再次异或。这是简单、快速和安全的。不需要复杂的库。

          【讨论】:

          • 你永远不应该编写自己的加密货币。绝不。永远。
          猜你喜欢
          • 2016-10-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-31
          • 2013-04-16
          • 2016-07-30
          • 2019-05-09
          • 1970-01-01
          相关资源
          最近更新 更多