1. 编写一个程序,将一段文字写入磁盘文件《姓名》.dat保存起来。要求文件的第一部分保存文件的结构(含密钥的变形码),第二部分是文字用密钥加密的密文。文件被重新打开时要求输入密码并验证密码并限定密码的输入次数(使用c语言)
时间: 2024-03-05 19:49:47 浏览: 66
以下是一个使用 C 语言实现的程序,可以实现您的需求:
``` c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <openssl/aes.h>
#define MAX_PASSWORD_ATTEMPTS 3 // 最大密码输入次数
// 加密函数
void encrypt(const char *plaintext, size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
AES_KEY aes_key;
uint8_t iv[AES_BLOCK_SIZE] = {0};
AES_set_encrypt_key(key, 128, &aes_key);
AES_cbc_encrypt((const uint8_t *) plaintext, ciphertext, plaintext_len, &aes_key, iv, AES_ENCRYPT);
}
// 解密函数
void decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *key, char *plaintext) {
AES_KEY aes_key;
uint8_t iv[AES_BLOCK_SIZE] = {0};
AES_set_decrypt_key(key, 128, &aes_key);
AES_cbc_encrypt(ciphertext, (uint8_t *) plaintext, ciphertext_len, &aes_key, iv, AES_DECRYPT);
}
// 保存文件函数
void save_file(const char *filename, const char *plaintext, size_t plaintext_len, const uint8_t *key) {
FILE *fp = fopen(filename, "wb");
if (!fp) {
printf("Failed to open file: %s\n", filename);
exit(EXIT_FAILURE);
}
// 加密明文
uint8_t *ciphertext = malloc(plaintext_len + AES_BLOCK_SIZE);
encrypt(plaintext, plaintext_len, key, ciphertext);
// 写入文件结构和密文
fwrite(key, 1, 16, fp);
fwrite(ciphertext, 1, plaintext_len + AES_BLOCK_SIZE, fp);
free(ciphertext);
fclose(fp);
}
// 加载文件函数
char *load_file(const char *filename, const uint8_t *key) {
FILE *fp = fopen(filename, "rb");
if (!fp) {
printf("Failed to open file: %s\n", filename);
exit(EXIT_FAILURE);
}
// 读取文件结构和密文
uint8_t key2[16], *ciphertext;
size_t ciphertext_len;
fread(key2, 1, 16, fp);
fseek(fp, 0, SEEK_END);
ciphertext_len = ftell(fp) - 16;
ciphertext = malloc(ciphertext_len);
fseek(fp, 16, SEEK_SET);
fread(ciphertext, 1, ciphertext_len, fp);
fclose(fp);
// 验证密钥
int attempts = 0;
while (true) {
if (memcmp(key, key2, 16) == 0) {
// 解密密文
char *plaintext = malloc(ciphertext_len);
decrypt(ciphertext, ciphertext_len, key, plaintext);
free(ciphertext);
return plaintext;
} else {
// 密钥错误,重新输入
printf("Invalid password. Please try again (%d/%d): ", attempts + 1, MAX_PASSWORD_ATTEMPTS);
if (++attempts >= MAX_PASSWORD_ATTEMPTS) {
// 密钥错误次数过多,退出程序
printf("Too many attempts. Exiting...\n");
free(ciphertext);
exit(EXIT_FAILURE);
}
uint8_t new_key[16];
if (fread(new_key, 1, 16, stdin) != 16) {
printf("Failed to read password.\n");
free(ciphertext);
exit(EXIT_FAILURE);
}
memcpy(key, new_key, 16);
}
}
}
// 测试程序
int main() {
const char *filename = "姓名.dat";
const char *plaintext = "Hello, World!";
const uint8_t key[16] = "my_secret_key_123";
save_file(filename, plaintext, strlen(plaintext), key);
char *ciphertext = load_file(filename, key);
printf("%s\n", ciphertext);
free(ciphertext);
return 0;
}
```
程序使用了 OpenSSL 库中的 AES 加密算法,要求在运行程序前先安装该库。程序包括以下功能:
1. `encrypt(plaintext, plaintext_len, key, ciphertext)`:加密函数,使用给定的密钥将明文加密成密文。
2. `decrypt(ciphertext, ciphertext_len, key, plaintext)`:解密函数,使用给定的密钥将密文解密成明文。
3. `save_file(filename, plaintext, plaintext_len, key)`:保存文件函数,将给定的明文使用给定的密钥加密后保存到文件中。
4. `load_file(filename, key)`:加载文件函数,从文件中读取密文并使用给定的密钥解密,要求在解密前输入密码并验证,最多允许输入 `MAX_PASSWORD_ATTEMPTS` 次密码。
程序运行后会将明文字符串加密并保存到名为“姓名.dat”的文件中,然后重新读取该文件并解密密文。如果输入的密码与保存时使用的密码不同,程序会提示重新输入,最多允许输入 `MAX_PASSWORD_ATTEMPTS` 次密码,超过次数后程序会退出。
阅读全文