Шифрование/дешифрование - Не удается расшифровать файл - C (СИ)
Формулировка задачи:
#include <openssl/rand.h>
#include <openssl/md5.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
unsigned long get_size_by_fd(int fd)
{
struct stat statbuf;
if (fstat(fd, &statbuf) < 0)
{
return 1;
}
return statbuf.st_size;
}
int main(int argc, char **argv)
{
char filename[1024];
AES_KEY key = { 0 };
enum
{
none = 0,
enc = 1,
dec = 2
} mode = none;
char password[256] = { 0 };
uint8_t pswmd5[16];
FILE * fp1 = 0;
FILE * fp2 = 0;
uint8_t plain_text[1024] = { 0 };
uint8_t enc_text[1024] = { 0 };
size_t cbdec;
size_t cbenc;
int i;
int status;
int file_descript;
unsigned long file_size;
for (i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "--help") == 0)
{
printf("usage: %s <mode> <filename>\n", basename(argv[0]));
printf("mode : {-enc|-dec}\n");
return 0;
}
if (strcmp(argv[i], "-enc") == 0)
{
mode = enc;
}
else if (strcmp(argv[i], "-dec") == 0)
{
mode = dec;
}
else if (*filename)
{
strncpy(filename, argv[i], sizeof(filename) - 4);
}
else
{
printf("invalid argument %s\n", argv[i]);
return -1;
}
}
if (!*filename)
{
printf("no filename provided\n");
return -1;
}
if (mode == none)
{
printf("no mode provided\n");
return -1;
}
printf("enter password:");
if (scanf("%255s", password) != 1)
{
printf("input error\n");
return -1;
}
if (strlen(password) < 6)
{
printf("password bad: too short\n");
return -1;
}
MD5(password, (strlen(password) + 1), pswmd5);
status = AES_set_encrypt_key(pswmd5, 16 * 8, &key);
printf("AES_set_encrypt_key(): status=%d\n", status);
fp1 = fopen(filename, "rb");
if (!fp1)
{
printf("can't open file '%s': %s\n", filename, strerror(errno));
return -1;
}
file_descript = open(filename, O_RDONLY);
file_size = get_size_by_fd(file_descript);
strcat(filename, mode == enc ? ".enc" : ".dec");
fp2 = fopen(filename, "wb");
if (!fp2)
{
printf("can't open file '%s': %s\n", filename, strerror(errno));
fclose(fp1);
return -1;
}
if (mode == enc)
{
while ((cbenc = fread(plain_text, 1, sizeof(enc_text) - 16, fp1)) > 0)
{
if (cbenc % 16 != 0)
{
cbenc = (cbenc / 16 + 1) * 16;
}
AES_encrypt(plain_text, enc_text, &key);
if (fwrite(enc_text, 1, cbenc, fp2) == 0)
{
fprintf(stderr, "can't write to file '%s': %d (%s)", filename,
errno, strerror(errno));
break;
}
}
}
else
{
while ((cbdec = fread(enc_text, 1, sizeof(enc_text), fp1)) > 0)
{
if (cbdec % 16 != 0)
{
cbdec = (cbdec / 16 + 1) * 16;
}
AES_decrypt(enc_text, plain_text, &key);
if (fwrite(plain_text, 1, cbdec, fp2) == 0)
{
fprintf(stderr, "can't write to file '%s': %d (%s)", filename,
errno, strerror(errno));
break;
}
}
}
fclose(fp2);
fclose(fp1);
return 0;
}Решение задачи: «Шифрование/дешифрование - Не удается расшифровать файл»
textual
Листинг программы
if (mode == enc)
{
status = AES_set_encrypt_key(pswmd5, 16 * 8, &key);
printf("AES_set_encrypt_key(): status=%d\n", status);
while ((cbenc = fread(plain_text, 1, sizeof(enc_text) - 16, fp1)) > 0)
{
if (cbenc % 16 != 0)
{
cbenc = (cbenc / 16 + 1) * 16;
}
AES_encrypt(plain_text, enc_text, &key);
if (fwrite(enc_text, 1, cbenc, fp2) == 0)
{
fprintf(stderr, "can't write to file '%s': %d (%s)",
filename, errno, strerror(errno));
break;
}
}
}
else
{
status = AES_set_decrypt_key(pswmd5, 16 * 8, &key);
printf("AES_set_decrypt_key(): status=%d\n", status);
while ((cbdec = fread(enc_text, 1, sizeof(enc_text) - 16, fp1)) > 0)
{
if (cbdec % 16 != 0)
{
cbdec = (cbdec / 16 + 1) * 16;
}
AES_decrypt(enc_text, plain_text, &key);
if (fwrite(plain_text, 1, cbdec, fp2) == 0)
{
fprintf(stderr, "can't write to file '%s': %d (%s)",
filename, errno, strerror(errno));
break;
}
}
}
Объяснение кода листинга программы
- Установка начального статуса и ключа шифрования
- Чтение и шифрование данных из первого файла
- Запись зашифрованных данных во второй файл
- Чтение и дешифрование данных из первого файла
- Запись дешифрованных данных во второй файл
- Вывод сообщения об ошибке, если не удалось записать данные во второй файл
- Вывод статуса и ключа шифрования
- Установка начального статуса и ключа дешифрования
- Чтение и дешифрование данных из первого файла
- Запись дешифрованных данных во второй файл
- Вывод сообщения об ошибке, если не удалось записать данные во второй файл
- Вывод статуса и ключа дешифрования
- Установка начального статуса и ключа шифрования
- Чтение и шифрование данных из первого файла
- Запись зашифрованных данных во второй файл
- Вывод сообщения об ошибке, если не удалось записать данные во второй файл
- Вывод статуса и ключа шифрования
- Установка начального статуса и ключа дешифрования
- Чтение и дешифрование данных из первого файла
- Запись дешифрованных данных во второй файл
- Вывод сообщения об ошибке, если не удалось записать данные во второй файл
- Вывод статуса и ключа дешифрования