任务详情
使用OpenSSL编程对内容为"所有同学的8位学号(数字)"的文件进行加密解密,密钥要包含你的8位学号,提交代码和运行结果截图。(选做(10’))
-
编译:gcc -g sm4txtcode.c -o sm4_en_de_txt -L/usr/lib -lssl -lcrypto
就像这样
-
运行:enout.txt是加密后的输出、deout.txt是解密后的输出、in.txt是输入、里面写的有学号
-
关于密钥:你不要急,密钥内嵌在代码里面,虽然不安全,但是这是测试。
-
操作环境ubuntu最新版(2023)
-
这里是源代码
点击查看代码
#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
// 检查命令行参数
if (argc != 4) {
printf("Usage: %s <input file> <encrypted output file> <decrypted output file>\n", argv[0]);
exit(EXIT_FAILURE);
}
// 初始化 OpenSSL
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
// 设置加密上下文
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
printf("Error creating context\n");
exit(EXIT_FAILURE);
}
const EVP_CIPHER *cipher = EVP_sm4_ecb();
unsigned char key[EVP_MAX_KEY_LENGTH] = {0};
unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
char *student_id = "20201326"; // 用你自己的8位学号替换
printf("学号%s\n",student_id);
strncpy(key, student_id, 8);
if (EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1) {
printf("Error setting up encryption context\n");
exit(EXIT_FAILURE);
}
// 打开输入文件
FILE *in_file = fopen(argv[1], "rb");
if (!in_file) {
printf("Error opening input file\n");
exit(EXIT_FAILURE);
}
// 打开加密输出文件
FILE *enc_file = fopen(argv[2], "wb");
if (!enc_file) {
printf("Error opening encrypted output file\n");
exit(EXIT_FAILURE);
}
// 加密输入文件并写入加密输出文件
unsigned char in_buf[BUF_SIZE] = {0};
unsigned char enc_buf[BUF_SIZE + EVP_MAX_BLOCK_LENGTH] = {0};
int num_bytes_read, enc_len;
while ((num_bytes_read = fread(in_buf, sizeof(unsigned char), BUF_SIZE, in_file)) > 0) {
if (EVP_EncryptUpdate(ctx, enc_buf, &enc_len, in_buf, num_bytes_read) != 1) {
printf("Error encrypting data\n");
exit(EXIT_FAILURE);
}
fwrite(enc_buf, sizeof(unsigned char), enc_len, enc_file);
}
if (num_bytes_read < 0) {
printf("Error reading input file\n");
exit(EXIT_FAILURE);
}
// 完成加密
if (EVP_EncryptFinal_ex(ctx, enc_buf, &enc_len) != 1) {
printf("Error finalizing encryption\n");
exit(EXIT_FAILURE);
}
fwrite(enc_buf, sizeof(unsigned char), enc_len, enc_file);
// 清理加密上下文
EVP_CIPHER_CTX_free(ctx);
// 关闭输入和输出文件
fclose(in_file);
fclose(enc_file);
// 设置解密上下文
ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
printf("Error creating context\n");
exit(EXIT_FAILURE);
}
if (EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv) != 1) {
printf("Error setting up decryption context\n");
exit(EXIT_FAILURE);
}
// 打开加密输入文件
enc_file = fopen(argv[2], "rb");
if (!enc_file) {
printf("Error opening encrypted input file\n");
exit(EXIT_FAILURE);
}
// 打开解密输出文件
FILE *dec_file = fopen(argv[3], "wb");
if (!dec_file) {
printf("Error opening decrypted output file\n");
exit(EXIT_FAILURE);
}
// 解密加密输入文件并写入解密输出文件
unsigned char dec_buf[BUF_SIZE + EVP_MAX_BLOCK_LENGTH] = {0};
int dec_len;
while ((num_bytes_read = fread(enc_buf, sizeof(unsigned char), BUF_SIZE + EVP_MAX_BLOCK_LENGTH, enc_file)) > 0) {
if (EVP_DecryptUpdate(ctx, dec_buf, &dec_len, enc_buf, num_bytes_read) != 1) {
printf("Error decrypting data\n");
exit(EXIT_FAILURE);
}
fwrite(dec_buf, sizeof(unsigned char), dec_len, dec_file);
}
if (num_bytes_read < 0) {
printf("Error reading encrypted input file\n");
exit(EXIT_FAILURE);
}
// 完成解密
if (EVP_DecryptFinal_ex(ctx, dec_buf, &dec_len) != 1) {
printf("Error finalizing decryption\n");
exit(EXIT_FAILURE);
}
fwrite(dec_buf, sizeof(unsigned char), dec_len, dec_file);
// 清理解密上下文
EVP_CIPHER_CTX_free(ctx);
// 关闭输入和输出文件
fclose(enc_file);
fclose(dec_file);
// 清理 OpenSSL
EVP_cleanup();
ERR_free_strings();
return 0;
}