Windows下用GPGME实现C语言PGP解密遇无效文件描述符错误求助
Windows下GPGME C语言PGP解密报错:无效文件描述符(错误码32779)
在Windows系统中尝试使用GPGME库通过C语言实现PGP解密功能,未找到完整可用的示例代码。调用gpgme_op_decrypt函数后程序报错:解密失败,错误码32779,对应“Bad file descriptor”(无效文件描述符)。以下是实现代码:
#include "pch.h" #include <gpgme.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> #include <windows.h> #include "pgp.h" #include <time.h> #include <stddef.h> #include <gpg-error.h> static gpgme_error_t passphrase_callback(void* hook_value, const char* uid_hint, const char* passphrase_info, int prev_was_bad, int fd) { const char* passphrase = (const char*)hook_value; gpgme_io_write(fd, passphrase, strlen(passphrase)); gpgme_io_write(fd, "\n", 1); return 0; } int PGPDecryptFile(const char* fromFilepath, const char* toFilePath, const char* private_key_filepath, const char* logFilePath) { gpgme_ctx_t ctx; gpgme_data_t in, out; const uint8_t private_key_password [13] = { 33, 44, 55, 66, 55, 33, 22, 11, 33, 44, 55, 66, '\0' }; // Initialize GPGME gpgme_check_version(NULL); gpgme_set_locale(NULL, 0, NULL); gpgme_check_version(NULL); // Create and initialize context gpgme_new(&ctx); gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); FILE* private_key_file; if (fopen_s(&private_key_file, private_key_filepath, "r") != 0) { AppendLogToFile(logFilePath, private_key_filepath); AppendLogToFile(logFilePath, "Error: Failed to open private key file for reading"); return 1; } if (!private_key_file) { AppendLogToFile(logFilePath, private_key_filepath); AppendLogToFile(logFilePath, "Error: Failed to open private key file for reading"); return 1; } gpgme_data_t private_key_data; if (gpgme_data_new_from_fd(&private_key_data, _fileno(private_key_file)) != GPG_ERR_NO_ERROR) { AppendLogToFile(logFilePath, "Error: Failed to create data buffer for private key"); fclose(private_key_file); return 1; } gpgme_set_passphrase_cb(ctx, passphrase_callback, (void*)private_key_password); // Set the private key in the context gpgme_error_t setProtocolResult = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); gpgme_error_t setEngineInfoResult = gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_OpenPGP, private_key_filepath, NULL); if (setProtocolResult != GPG_ERR_NO_ERROR || setEngineInfoResult != GPG_ERR_NO_ERROR) { AppendLogToFile(logFilePath, "Error: Failed to set private key in the context"); if (setProtocolResult != GPG_ERR_NO_ERROR) { AppendLogToFile(logFilePath, "Error setting protocol"); } if (setEngineInfoResult != GPG_ERR_NO_ERROR) { AppendLogToFile(logFilePath, "Error setting engine info"); } gpgme_data_release(private_key_data); fclose(private_key_file); return 1; } // Prepare data for decryption FILE* file; if (fopen_s(&file, fromFilepath, "rb") != 0) { //fprintf(stderr, "Error: Failed to open file for reading.\n"); AppendLogToFile(logFilePath, fromFilepath); AppendLogToFile(logFilePath, "Error: Failed to open file for reading"); gpgme_data_release(private_key_data); fclose(private_key_file); return 1; } if (!file) { AppendLogToFile(logFilePath, fromFilepath); AppendLogToFile(logFilePath, "Error: Failed to open file for reading"); gpgme_data_release(private_key_data); fclose(private_key_file); return 1; } gpgme_data_new_from_fd(&in, _fileno(file)); gpgme_data_new(&out); // Decrypt data gpgme_error_t decryptResult = gpgme_op_decrypt(ctx,in , out); if (decryptResult != GPG_ERR_NO_ERROR) { int errCode = gpgme_err_code(decryptResult); char errorMessage[256]; snprintf(errorMessage, sizeof(errorMessage), "Error: Failed to decrypt data. Error code: %d", errCode); AppendLogToFile(logFilePath, errorMessage); fclose(file); gpgme_data_release(private_key_data); fclose(private_key_file); return 1; } char* decrypted_data = gpgme_data_release_and_get_mem(out, NULL); FILE* decrypted_file; if (fopen_s(&decrypted_file, toFilePath, "wb") != 0) { AppendLogToFile(logFilePath, toFilePath); AppendLogToFile(logFilePath, "Error: Failed to create decrypted file for writing"); fclose(file); gpgme_data_release(private_key_data); fclose(private_key_file); free(decrypted_data); return 1; } fwrite(decrypted_data, 1, strlen(decrypted_data), decrypted_file); fclose(file); fclose(decrypted_file); gpgme_data_release(private_key_data); free(decrypted_data); gpgme_data_release(in); gpgme_release(ctx); fclose(private_key_file); return 0; }
测试该代码需安装Gpg4win,同时在Visual Studio中需完成以下配置:
- 将
Gpg4win\include添加至“附加包含目录”属性(位于C/C++常规选项卡下) - 将
Gpg4win\bin和Gpg4win\lib添加至“附加库目录”属性(位于链接器常规选项卡下) - 将
libgpgme.imp添加至“附加依赖项”属性(位于链接器输入选项卡下)
内容的提问来源于stack exchange,提问作者Anas
相关产品推荐
相关产品推荐

