我尝试在C中创建一个程序,使用openssl-lib
加密目录中的所有文件。我用ntfw()
读取目录并将文件名传递给处理函数handleCryptProcess()
。功能执行波纹管程序。
我使用RSA公钥来加密文件。
我的问题是,当我的文件夹包含多个文件时,我会收到细分错误。这与处理程序功能有关。我想,上述一个或多个程序无法有效处理内存。
当我的文件夹包含 ONLY ONE 文件时,该程序成功。
Bellow是我的处理函数:
#include "crypt.h"
/**
* - First we generate the filepath of our output file with getCyphertextFilePath().
* - The we check (cryptFlag) and determine if we want to encrypt or decrypt the file.
* - encryptRSAFile() tries to encrypt the file under (fpath).
* decryptRSAFile() tries to decrypt the file under (fpath).
* - We delete the original file using unlink().
* - Lastly, rename the new file back to original filename with rename().
*/
int handleCryptProcess(const char *fpath, const en_de_crypt_flag cryptFlag) {
int status;
char *new_fpath = NULL; /* Hold the file path of our output file */
status = getOutputFilePath(fpath, &new_fpath);
if (status == -1) {
return -1; /* Could not get the output filepath. */
}
if (cryptFlag == ENCRYPT) { /* We want to encrypt our file. */
status = encryptRSAFile(fpath, new_fpath);
} else { /* We want to decrypt our file. */
status = decryptRSAFile(fpath, new_fpath);
}
if (status == -1) {
return -1; /* Failed to encrypt/decrypt fpath. */
}
status = unlink(fpath); /* Delete the original file. */
if (status == -1) {
return -1; /* Failed to delete original fpath. */
}
status = rename(new_fpath, fpath); /* Rename our file. */
if (status == -1) {
return -1; /* Failed to rename back to original fpath. */
}
return 0; /* File encrypted/decrypted successfully. */
}
这是我用来创建密文的那个:
#include "crypt.h"
/**
* We use RSA asymmetric cryptography to create our cyphertext.
* The public key was passed to (rsaPubKey) when we initialized it
* in main() with publicRSATextKeyToStruct().
* (fpath) is the file we want to encrypt.
* (cyphertext_fpath) is our cyphertext.
*/
int encryptRSAFile(const char *fpath, const char *cyphertext_fpath) {
FILE *fin, *fout;
/**
* Open the plaintext file we want to encrypt.
*/
fin = fopen(fpath, "rb");
if (fin == NULL) {
return -1;
}
/**
* Create a cyphertext file for writing to.
*/
fout = fopen(cyphertext_fpath, "wb");
if (fout == NULL) {
return -1;
}
/**
* The EVP_PKEY_new() function allocates an empty EVP_PKEY
* structure which is used by OpenSSL to store private keys.
*/
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_CIPHER_CTX ctx; /* Cipher contex ctx. */
unsigned char buffer[RSA_KEY_SIZE]; /* Buffer that holds out plaintext. */
unsigned char buffer_out[RSA_KEY_SIZE + EVP_MAX_IV_LENGTH]; /* Buffer that holds the cyphertext. */
size_t len;
int len_out;
/**
* ek is an array of buffers where the public key encrypted secret key will be written,
* each buffer must contain enough room for the corresponding encrypted key.
* That is ek[i] must have room for EVP_PKEY_size(pubk[i]) bytes
*/
unsigned char *ek = NULL;
int eklen;
uint32_t eklen_n;
unsigned char iv[EVP_MAX_IV_LENGTH]; /* Buffer where the generated IV is written to */
if (!EVP_PKEY_assign_RSA(pkey, rsaPubKey)) {
return -1;
}
EVP_CIPHER_CTX_init(&ctx); /* Initialize a new context. */
ek = malloc(EVP_PKEY_size(pkey));
/**
* EVP_SealInit() initializes a cipher context (ctx) for encryption
* with cipher type using a random secret key and (iv).
* Cipher type we use is AES 256.
* The secret key is encrypted using our public key (pkey).
*/
if (!EVP_SealInit(&ctx, EVP_aes_256_cbc(), &ek, &eklen, iv, &pkey, 1)) {
return 2;
}
eklen_n = htonl(eklen);
if (fwrite(&eklen_n, sizeof eklen_n, 1, fout) != 1) {
return 3;
}
if (fwrite(ek, eklen, 1, fout) != 1) {
return 4;
}
if (fwrite(iv, EVP_CIPHER_iv_length(EVP_aes_256_cbc()), 1, fout) != 1) {
return 5;
}
while ((len = fread(buffer, 1, sizeof buffer, fin)) > 0) {
if (!EVP_SealUpdate(&ctx, buffer_out, &len_out, buffer, len)) {
return 6;
}
if (fwrite(buffer_out, len_out, 1, fout) != 1) {
return 7;
}
}
if (ferror(fin)) {
return 8;
}
if (!EVP_SealFinal(&ctx, buffer_out, &len_out)) {
return 9;
}
if (fwrite(buffer_out, len_out, 1, fout) != 1) {
return 10;
}
EVP_PKEY_free(pkey);
free(ek);
fclose(fin);
fclose(fout);
return 0;
}
这是否与return
值有关?也许是我如何检查错误状态。但是我无法理解,openssl文档在这方面并不是很支持。
为了更清楚地了解发生了什么,我发布了一个例子。
假设我们有两个文件。
程序开始,读取File1对其进行加密并转到File2。
在File2上,我的代码在加密程序的以下情况下中断:
fwrite(ek, eklen, 1, fout) != 1
然后,我得到了一个分段错误。这并不总是发生在第二个文件中。如果可能发生在第三个之后,但永远不会发生。
如果我有三个文件,我可能会加密第一个文件,第二个文件会破坏程序,第三个文件会破坏程序。