Openssl的头文件和库
C/C++使用openssl,需要openssl的头文件和库,这些都在安装包里。从http://slproweb.com/products/Win32OpenSSL.html下载已经编译好的包含 lib 和 include 文件的安装包。
也可以从官网下载源码,再编译成安装包,但编译有点复杂,编译过程中可能产生各种的问题,不建议使用。
C++使用示例
Windows下在C++使用OpenSSL库的示例
以下是在Windows环境下使用C++和OpenSSL库的完整指南,包括安装、配置和代码示例。
1. 安装OpenSSL
方法1:使用预编译的二进制文件
- 访问 OpenSSL官方下载页面 或 Win32/Win64 OpenSSL安装器
- 下载适合您系统的安装包(32位或64位)
- 运行安装程序,按照向导完成安装
方法2:使用vcpkg包管理器
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat
vcpkg install openssl:x64-windows # 64位
# 或
vcpkg install openssl:x86-windows # 32位
vcpkg integrate install
2. 配置Visual Studio项目
手动配置
- 打开项目属性(右键项目 -> 属性)
- 添加包含目录:
- C/C++ -> 常规 -> 附加包含目录:添加
C:\OpenSSL-Win64\include
(根据安装位置调整)
- C/C++ -> 常规 -> 附加包含目录:添加
- 添加库目录:
- 链接器 -> 常规 -> 附加库目录:添加
C:\OpenSSL-Win64\lib
(根据安装位置调整)
- 链接器 -> 常规 -> 附加库目录:添加
- 添加依赖库:
- 链接器 -> 输入 -> 附加依赖项:添加
libssl.lib
和libcrypto.lib
- 链接器 -> 输入 -> 附加依赖项:添加
使用vcpkg配置
如果使用vcpkg并且运行了vcpkg integrate install
,则无需额外配置,可以直接使用库。
3. C++代码示例
示例1:基本的OpenSSL初始化和清理
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <iostream>
int main() {
// 初始化OpenSSL库
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
std::cout << "OpenSSL版本: " << OpenSSL_version(OPENSSL_VERSION) << std::endl;
// 清理OpenSSL资源
EVP_cleanup();
ERR_free_strings();
return 0;
}
示例2:使用RSA进行加密和解密
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <iostream>
#include <string>
#include <vector>
// 错误处理函数
void handleErrors() {
ERR_print_errors_fp(stderr);
abort();
}
// 生成RSA密钥对并保存到文件
void generateRSAKeyPair(const char* privateKeyFile, const char* publicKeyFile) {
EVP_PKEY* pkey = NULL;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (!ctx) handleErrors();
if (EVP_PKEY_keygen_init(ctx) <= 0) handleErrors();
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) handleErrors();
if (EVP_PKEY_keygen(ctx, &pkey) <= 0) handleErrors();
// 保存私钥
FILE* fp = fopen(privateKeyFile, "wb");
if (!fp) handleErrors();
if (!PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL)) handleErrors();
fclose(fp);
// 保存公钥
fp = fopen(publicKeyFile, "wb");
if (!fp) handleErrors();
if (!PEM_write_PUBKEY(fp, pkey)) handleErrors();
fclose(fp);
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(ctx);
}
// 使用公钥加密数据
std::vector<unsigned char> rsaEncrypt(const char* publicKeyFile, const std::string& plainText) {
FILE* fp = fopen(publicKeyFile, "rb");
if (!fp) handleErrors();
EVP_PKEY* pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
fclose(fp);
if (!pkey) handleErrors();
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ctx) handleErrors();
if (EVP_PKEY_encrypt_init(ctx) <= 0) handleErrors();
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) handleErrors();
size_t outlen;
if (EVP_PKEY_encrypt(ctx, NULL, &outlen,
(const unsigned char*)plainText.c_str(),
plainText.length()) <= 0) handleErrors();
std::vector<unsigned char> encrypted(outlen);
if (EVP_PKEY_encrypt(ctx, encrypted.data(), &outlen,
(const unsigned char*)plainText.c_str(),
plainText.length()) <= 0) handleErrors();
encrypted.resize(outlen);
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
return encrypted;
}
// 使用私钥解密数据
std::string rsaDecrypt(const char* privateKeyFile, const std::vector<unsigned char>& cipherText) {
FILE* fp = fopen(privateKeyFile, "rb");
if (!fp) handleErrors();
EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if (!pkey) handleErrors();
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ctx) handleErrors();
if (EVP_PKEY_decrypt_init(ctx) <= 0) handleErrors();
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) handleErrors();
size_t outlen;
if (EVP_PKEY_decrypt(ctx, NULL, &outlen, cipherText.data(), cipherText.size()) <= 0)
handleErrors();
std::vector<unsigned char> decrypted(outlen);
if (EVP_PKEY_decrypt(ctx, decrypted.data(), &outlen, cipherText.data(), cipherText.size()) <= 0)
handleErrors();
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
return std::string(decrypted.begin(), decrypted.begin() + outlen);
}
int main() {
// 初始化OpenSSL
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
const char* privateKeyFile = "private.pem";
const char* publicKeyFile = "public.pem";
std::string message = "This is a secret message for RSA encryption!";
// 生成RSA密钥对
generateRSAKeyPair(privateKeyFile, publicKeyFile);
std::cout << "RSA密钥对已生成.\n";
// 加密消息
std::vector<unsigned char> encrypted = rsaEncrypt(publicKeyFile, message);
std::cout << "消息已加密,密文大小: " << encrypted.size() << " 字节\n";
// 解密消息
std::string decrypted = rsaDecrypt(privateKeyFile, encrypted);
std::cout << "解密后的消息: " << decrypted << "\n";
// 清理
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return 0;
}
示例3:使用AES-256-GCM进行加密和解密
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
void handleErrors() {
ERR_print_errors_fp(stderr);
abort();
}
// AES-GCM 加密
std::vector<unsigned char> aesGcmEncrypt(
const std::string& plaintext,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
std::vector<unsigned char>& tag) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) handleErrors();
// 初始化加密操作
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
handleErrors();
// 设置IV长度
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size(), NULL))
handleErrors();
// 初始化密钥和IV
if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key.data(), iv.data()))
handleErrors();
// 提供要加密的明文
int len = 0;
int ciphertext_len = 0;
std::vector<unsigned char> ciphertext(plaintext.size() + EVP_MAX_BLOCK_LENGTH);
if (1 != EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
(const unsigned char*)plaintext.c_str(), plaintext.size()))
handleErrors();
ciphertext_len = len;
// 加密最终块
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len))
handleErrors();
ciphertext_len += len;
// 获取认证标签
tag.resize(16);
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag.data()))
handleErrors();
EVP_CIPHER_CTX_free(ctx);
ciphertext.resize(ciphertext_len);
return ciphertext;
}
// AES-GCM 解密
std::string aesGcmDecrypt(
const std::vector<unsigned char>& ciphertext,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv,
const std::vector<unsigned char>& tag) {
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) handleErrors();
// 初始化解密操作
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
handleErrors();
// 设置IV长度
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size(), NULL))
handleErrors();
// 初始化密钥和IV
if (1 != EVP_DecryptInit_ex(ctx, NULL, NULL, key.data(), iv.data()))
handleErrors();
// 提供密文
int len = 0;
int plaintext_len = 0;
std::vector<unsigned char> plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH);
if (1 != EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext.data(), ciphertext.size()))
handleErrors();
plaintext_len = len;
// 设置预期的标签值
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), (void*)tag.data()))
handleErrors();
// 验证并解密最终块
int ret = EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len);
EVP_CIPHER_CTX_free(ctx);
if (ret > 0) {
plaintext_len += len;
plaintext.resize(plaintext_len);
return std::string(plaintext.begin(), plaintext.end());
} else {
// 认证失败
return "认证失败!";
}
}
int main() {
// 初始化OpenSSL
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
// 生成随机密钥 (256 bits)
std::vector<unsigned char> key(32);
if (RAND_bytes(key.data(), key.size()) != 1)
handleErrors();
// 生成随机IV (96 bits 是GCM的推荐值)
std::vector<unsigned char> iv(12);
if (RAND_bytes(iv.data(), iv.size()) != 1)
handleErrors();
std::string plaintext = "这是一个使用AES-256-GCM加密的机密消息!";
std::cout << "原始消息: " << plaintext << std::endl;
// 加密
std::vector<unsigned char> tag;
std::vector<unsigned char> ciphertext = aesGcmEncrypt(plaintext, key, iv, tag);
std::cout << "加密完成,密文大小: " << ciphertext.size() << " 字节" << std::endl;
std::cout << "认证标签大小: " << tag.size() << " 字节" << std::endl;
// 解密
std::string decryptedText = aesGcmDecrypt(ciphertext, key, iv, tag);
std::cout << "解密后的消息: " << decryptedText << std::endl;
// 使用错误的标签尝试解密(模拟篡改)
std::vector<unsigned char> wrongTag = tag;
wrongTag[0] ^= 1; // 修改一个位
std::string failedDecrypt = aesGcmDecrypt(ciphertext, key, iv, wrongTag);
std::cout << "使用错误标签解密: " << failedDecrypt << std::endl;
// 清理
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return 0;
}
示例4:生成和验证ECDSA签名(类似于原始示例)
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#include <openssl/pem.h>
#include <iostream>
#include <vector>
#include <string>
void handleErrors() {
ERR_print_errors_fp(stderr);
abort();
}
// 生成EC密钥
EC_KEY* generateEcKey() {
EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
if (!ec_key || !EC_KEY_generate_key(ec_key)) {
handleErrors();
}
return ec_key;
}
// 将EC密钥保存到文件
void saveEcKey(EC_KEY* ec_key, const char* privateKeyFile, const char* publicKeyFile) {
// 保存私钥
FILE* fp = fopen(privateKeyFile, "wb");
if (!fp) handleErrors();
if (!PEM_write_ECPrivateKey(fp, ec_key, NULL, NULL, 0, NULL, NULL))
handleErrors();
fclose(fp);
// 保存公钥
fp = fopen(publicKeyFile, "wb");
if (!fp) handleErrors();
if (!PEM_write_EC_PUBKEY(fp, ec_key))
handleErrors();
fclose(fp);
}
// 从文件加载EC密钥
EC_KEY* loadEcPrivateKey(const char* privateKeyFile) {
FILE* fp = fopen(privateKeyFile, "rb");
if (!fp) handleErrors();
EC_KEY* ec_key = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if (!ec_key) handleErrors();
return ec_key;
}
EC_KEY* loadEcPublicKey(const char* publicKeyFile) {
FILE* fp = fopen(publicKeyFile, "rb");
if (!fp) handleErrors();
EC_KEY* ec_key = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
fclose(fp);
if (!ec_key) handleErrors();
return ec_key;
}
// 签名数据
std::vector<unsigned char> signData(EC_KEY* ec_key, const std::string& data) {
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
if (!mdctx) handleErrors();
EVP_PKEY* pkey = EVP_PKEY_new();
if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey, ec_key)) handleErrors();
if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) <= 0) handleErrors();
if (EVP_DigestSignUpdate(mdctx, data.c_str(), data.size()) <= 0) handleErrors();
// 获取签名大小
size_t sig_len = 0;
if (EVP_DigestSignFinal(mdctx, NULL, &sig_len) <= 0) handleErrors();
// 生成签名
std::vector<unsigned char> signature(sig_len);
if (EVP_DigestSignFinal(mdctx, signature.data(), &sig_len) <= 0) handleErrors();
signature.resize(sig_len);
EVP_MD_CTX_free(mdctx);
EVP_PKEY_free(pkey);
return signature;
}
// 验证签名
bool verifySignature(EC_KEY* ec_key, const std::string& data, const std::vector<unsigned char>& signature) {
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
if (!mdctx) handleErrors();
EVP_PKEY* pkey = EVP_PKEY_new();
if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey, ec_key)) handleErrors();
if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) <= 0) handleErrors();
if (EVP_DigestVerifyUpdate(mdctx, data.c_str(), data.size()) <= 0) handleErrors();
// 验证签名
int result = EVP_DigestVerifyFinal(mdctx, signature.data(), signature.size());
EVP_MD_CTX_free(mdctx);
EVP_PKEY_free(pkey);
return result == 1;
}
int main() {
// 初始化OpenSSL
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
const char* privateKeyFile = "ec_private.pem";
const char* publicKeyFile = "ec_public.pem";
std::string message = "Hello, ECDSA Signing with OpenSSL!";
// 生成并保存密钥
EC_KEY* ec_key = generateEcKey();
saveEcKey(ec_key, privateKeyFile, publicKeyFile);
EC_KEY_free(ec_key);
std::cout << "EC密钥对已生成并保存.\n";
// 从文件加载密钥
EC_KEY* priv_key = loadEcPrivateKey(privateKeyFile);
EC_KEY* pub_key = loadEcPublicKey(publicKeyFile);
// 签名数据
std::vector<unsigned char> signature = signData(priv_key, message);
std::cout << "签名已生成,大小: " << signature.size() << " 字节\n";
// 验证签名
bool is_valid = verifySignature(pub_key, message, signature);
std::cout << "签名验证: " << (is_valid ? "成功" : "失败") << "\n";
// 篡改消息并验证
std::string tampered_message = message + "!";
bool tampered_valid = verifySignature(pub_key, tampered_message, signature);
std::cout << "篡改后的消息签名验证: " << (tampered_valid ? "成功" : "失败") << "\n";
// 清理
EC_KEY_free(priv_key);
EC_KEY_free(pub_key);
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return 0;
}
4. 部署注意事项
确保DLL文件可以被应用程序找到:
- 将
libssl-1_1-x64.dll
和libcrypto-1_1-x64.dll
(或相应版本)放在应用程序目录中 - 或者确保它们在系统PATH环境变量包含的目录中
- 将
构建项目时注意:
- 确保编译版本(Debug/Release)与OpenSSL库的版本(Debug/Release)匹配
- 32位应用程序应使用32位OpenSSL库,64位应用程序应使用64位OpenSSL库
版本兼容性:
- 保持应用程序使用的OpenSSL版本与部署环境一致
- 考虑静态链接OpenSSL库,以避免版本依赖问题
以上示例涵盖了在Windows上使用C++和OpenSSL进行常见加密操作的基本用法,包括RSA加密/解密、AES-GCM加密/解密以及ECDSA签名/验证。您可以根据需要调整和扩展这些示例。
MFC使用示例
Windows下在MFC中使用OpenSSL库的示例
在MFC应用程序中使用OpenSSL库需要几个步骤:安装OpenSSL、配置项目以及编写代码。以下是具体指南:
1. 安装OpenSSL
首先需要在Windows上安装OpenSSL:
- 从官方网站下载OpenSSL: https://www.openssl.org/source/ 或使用预编译版本
- 或使用vcpkg包管理器:
vcpkg install openssl:x86-windows
或vcpkg install openssl:x64-windows
2. 配置MFC项目
在Visual Studio中配置MFC项目:
- 右键点击项目 → 属性
- 配置包含目录:
- C/C++ → 常规 → 附加包含目录: 添加
C:\path\to\openssl\include
- C/C++ → 常规 → 附加包含目录: 添加
- 配置库目录:
- 链接器 → 常规 → 附加库目录: 添加
C:\path\to\openssl\lib
- 链接器 → 常规 → 附加库目录: 添加
- 添加依赖库:
- 链接器 → 输入 → 附加依赖项: 添加
libssl.lib
和libcrypto.lib
- 链接器 → 输入 → 附加依赖项: 添加
3. MFC应用程序示例
下面是一个在MFC对话框应用程序中使用OpenSSL进行ECC签名的简单示例:
在头文件中添加声明
// ... existing code ...
#pragma once
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#include <vector>
#include <string>
class CYourDialog : public CDialogEx
{
// ... existing code ...
private:
// OpenSSL相关函数
EC_KEY* GenerateECCKey();
std::vector<unsigned char> SignData(EC_KEY* ec_key, const std::string& data);
bool VerifySignature(EC_KEY* ec_key, const std::string& data, const std::vector<unsigned char>& signature);
void HandleOpenSSLErrors();
public:
afx_msg void OnBnClickedButtonSign();
// ... existing code ...
};
在实现文件中添加代码
// ... existing code ...
// 初始化时加载OpenSSL
BOOL CYourDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 初始化OpenSSL
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
return TRUE;
}
// 处理OpenSSL错误
void CYourDialog::HandleOpenSSLErrors()
{
CString errorMsg;
char errBuf[256];
unsigned long err;
while ((err = ERR_get_error()) != 0) {
ERR_error_string_n(err, errBuf, sizeof(errBuf));
errorMsg += errBuf;
errorMsg += _T("\n");
}
AfxMessageBox(errorMsg, MB_ICONERROR);
}
// 生成ECC密钥
EC_KEY* CYourDialog::GenerateECCKey()
{
EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_secp521r1);
if (!ec_key || !EC_KEY_generate_key(ec_key)) {
HandleOpenSSLErrors();
return nullptr;
}
return ec_key;
}
// 签名数据
std::vector<unsigned char> CYourDialog::SignData(EC_KEY* ec_key, const std::string& data)
{
std::vector<unsigned char> signature;
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
EVP_PKEY* pkey = EVP_PKEY_new();
if (!mdctx || !pkey) {
HandleOpenSSLErrors();
goto cleanup;
}
if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key)) {
HandleOpenSSLErrors();
goto cleanup;
}
if (EVP_DigestSignInit(mdctx, nullptr, EVP_sha512(), nullptr, pkey) <= 0) {
HandleOpenSSLErrors();
goto cleanup;
}
if (EVP_DigestSignUpdate(mdctx, data.c_str(), data.size()) <= 0) {
HandleOpenSSLErrors();
goto cleanup;
}
// 获取签名长度
size_t sig_len = 0;
if (EVP_DigestSignFinal(mdctx, nullptr, &sig_len) <= 0) {
HandleOpenSSLErrors();
goto cleanup;
}
// 执行签名
signature.resize(sig_len);
if (EVP_DigestSignFinal(mdctx, signature.data(), &sig_len) <= 0) {
HandleOpenSSLErrors();
signature.clear();
goto cleanup;
}
signature.resize(sig_len);
cleanup:
if (mdctx) EVP_MD_CTX_free(mdctx);
if (pkey) EVP_PKEY_free(pkey);
return signature;
}
// 验证签名
bool CYourDialog::VerifySignature(EC_KEY* ec_key, const std::string& data, const std::vector<unsigned char>& signature)
{
bool result = false;
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
EVP_PKEY* pkey = EVP_PKEY_new();
if (!mdctx || !pkey) {
HandleOpenSSLErrors();
goto cleanup;
}
if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key)) {
HandleOpenSSLErrors();
goto cleanup;
}
if (EVP_DigestVerifyInit(mdctx, nullptr, EVP_sha512(), nullptr, pkey) <= 0) {
HandleOpenSSLErrors();
goto cleanup;
}
if (EVP_DigestVerifyUpdate(mdctx, data.c_str(), data.size()) <= 0) {
HandleOpenSSLErrors();
goto cleanup;
}
if (EVP_DigestVerifyFinal(mdctx, signature.data(), signature.size()) == 1) {
result = true;
}
cleanup:
if (mdctx) EVP_MD_CTX_free(mdctx);
if (pkey) EVP_PKEY_free(pkey);
return result;
}
// 点击签名按钮的处理函数
void CYourDialog::OnBnClickedButtonSign()
{
CString message;
GetDlgItemText(IDC_EDIT_MESSAGE, message);
if (message.IsEmpty()) {
AfxMessageBox(_T("请输入要签名的消息"));
return;
}
EC_KEY* ec_key = GenerateECCKey();
if (!ec_key) return;
std::string messageStr(CT2A(message));
std::vector<unsigned char> signature = SignData(ec_key, messageStr);
if (!signature.empty()) {
bool is_valid = VerifySignature(ec_key, messageStr, signature);
CString result;
result.Format(_T("签名长度: %d 字节\r\n签名验证: %s"),
signature.size(),
is_valid ? _T("成功") : _T("失败"));
SetDlgItemText(IDC_EDIT_RESULT, result);
}
EC_KEY_free(ec_key);
}
void CYourDialog::OnDestroy()
{
CDialogEx::OnDestroy();
// 清理OpenSSL
EVP_cleanup();
ERR_free_strings();
}
4. 在资源文件中添加UI控件
在对话框资源中添加:
- 一个编辑框(IDC_EDIT_MESSAGE)用于输入消息
- 一个按钮(IDC_BUTTON_SIGN)用于触发签名
- 一个编辑框(IDC_EDIT_RESULT)用于显示结果
5. 注意事项
- 确保使用正确版本的OpenSSL库(32位/64位)与项目配置匹配
- 在Debug和Release配置中都要配置包含目录和库目录
- 处理好OpenSSL库的内存管理,避免内存泄漏
- 如有多线程需求,确保OpenSSL线程安全配置
这个示例展示了如何在MFC应用程序中集成OpenSSL库进行ECC签名和验证,您可以根据需要进行修改和扩展。