下面程序读取public.pem文件内容作为公钥并加密文件,现在我希望直接将公钥内容硬编码到代码中,假如我的public.pem文件内容为:
-----BEGIN PUBLIC KEY-----
xxxxxxxx
-----END PUBLIC KEY-----
我的代码为:
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/applink.c>
#include <stdio.h>
#include <stdlib.h>
#define AES_KEY_SIZE 32
#define RSA_KEY_SIZE 2048
#define GCM_IV_LEN 12
#define GCM_TAG_LEN 16
#define CHECK(cond, msg) do {
if (!(cond)) {
fprintf(stderr, “错误: %s (位置: %s:%d)\n”, msg, FILE, LINE);
ERR_print_errors_fp(stderr);
exit(EXIT_FAILURE);
}
} while(0)
EVP_PKEY* load_public_key(const char* pubkey_path) {
BIO* bio = BIO_new_file(pubkey_path, “r”);
CHECK(bio != NULL, “无法打开公钥文件”);
EVP_PKEY* pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
CHECK(pubkey != NULL, “解析公钥失败”);
BIO_free(bio);
return pubkey;
}
unsigned char* rsa_encrypt(EVP_PKEY* pubkey, const unsigned char* aes_key, size_t* encrypted_len) {
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pubkey, NULL);
CHECK(ctx != NULL, “创建RSA上下文失败”);
CHECK(EVP_PKEY_encrypt_init(ctx) > 0, “初始化RSA加密失败”);
size_t outlen;
CHECK(EVP_PKEY_encrypt(ctx, NULL, &outlen, aes_key, AES_KEY_SIZE) > 0, “计算缓冲区大小失败”);
unsigned char* encrypted = malloc(outlen);
CHECK(encrypted != NULL, “内存分配失败”);
CHECK(EVP_PKEY_encrypt(ctx, encrypted, &outlen, aes_key, AES_KEY_SIZE) > 0, “RSA加密失败”);
encrypted_len = outlen;
EVP_PKEY_CTX_free(ctx);
return encrypted;
}
void aes_gcm_encrypt(
const unsigned char plaintext, size_t plaintext_len,
const unsigned char* aes_key,
unsigned char* iv, unsigned char* tag,
unsigned char** ciphertext, size_t* ciphertext_len)
{
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
CHECK(ctx != NULL, “创建AES上下文失败”);
CHECK(RAND_bytes(iv, GCM_IV_LEN) > 0, “生成IV失败”);
CHECK(EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, aes_key, iv) > 0, “初始化AES失败”);
ciphertext = malloc(plaintext_len + EVP_MAX_BLOCK_LENGTH);
CHECK(ciphertext != NULL, “内存分配失败”);
int len;
CHECK(EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len) > 0, “加密失败”);
ciphertext_len = len;
CHECK(EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) > 0, “最终加密失败”);
ciphertext_len += len;
CHECK(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, GCM_TAG_LEN, tag) > 0, “获取标签失败”);
EVP_CIPHER_CTX_free(ctx);
}
int main() {
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
unsigned char aes_key[AES_KEY_SIZE];
CHECK(RAND_bytes(aes_key, sizeof(aes_key)) > 0, “生成AES密钥失败”);
EVP_PKEY pubkey = load_public_key(“public.pem”);
size_t encrypted_aes_len;
unsigned char encrypted_aes = rsa_encrypt(pubkey, aes_key, &encrypted_aes_len);
FILE input_file = fopen(“1.txt”, “rb”);
CHECK(input_file != NULL, “无法打开输入文件”);
fseek(input_file, 0, SEEK_END);
long plaintext_len = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
unsigned char plaintext = malloc(plaintext_len);
CHECK(plaintext != NULL, “内存分配失败”);
fread(plaintext, 1, plaintext_len, input_file);
fclose(input_file);
unsigned char iv[GCM_IV_LEN];
unsigned char tag[GCM_TAG_LEN];
unsigned char ciphertext;
size_t ciphertext_len;
aes_gcm_encrypt((unsigned char)plaintext, plaintext_len, aes_key, iv, tag, &ciphertext, &ciphertext_len);
FILE* out = fopen(“encrypted.bin”, “wb”);
CHECK(out != NULL, “无法创建输出文件”);
fwrite(&encrypted_aes_len, sizeof(size_t), 1, out);
fwrite(encrypted_aes, 1, encrypted_aes_len, out);
fwrite(iv, 1, GCM_IV_LEN, out);
fwrite(tag, 1, GCM_TAG_LEN, out);
fwrite(&ciphertext_len, sizeof(size_t), 1, out);
fwrite(ciphertext, 1, ciphertext_len, out);
fclose(out);
free(encrypted_aes);
free(ciphertext);
EVP_PKEY_free(pubkey);
printf(“加密成功!输出文件: encrypted.bin\n”);
return 0;
}