轻松看懂的加解密系列(2) —— “RSA非对称加解密实例”保姆级讲解

本文详细介绍了如何在Windows环境下,使用MFC对话框程序通过WindowsCryptoAPIs实现RSA非对称加密(公钥加密)和解密(私钥解密)的过程,包括密钥生成、存储、加密、解密及密钥管理的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

​​​​​​​

【实例介绍】:      

        在《轻松看懂的加解密系列(1)》中,我们用一个简单的 Windows Console 程序介绍了 Windows Crypto APIs 是如何进行 AES 对称加密和解密的。这次将通过另一个 Windows MFC 对话框程序,来讲解更复杂一些的 RSA 非对称加密接口的运用。当然本实例继续使用 Windows Crypto APIs。

图-1

       看到【图-1】中的对话框,如果稍有 Windows 编程基础,应该大致就能猜到点击【Encrypt By Public Key】按钮或【Decrypt By Private Key】按钮会各触发一个事件响应函数。函数名分别为【OnBnClickedButtonEncrypt】和【OnBnClickedButtonDecrypt】。其中【OnBnClickedButtonEncrypt】函数会从第一个对话框中取出用户输入的明文,然后用生成的公钥加密后,将密文以及对应生成的私钥一并存储在目标注册表项下。【OnBnClickedButtonDecrypt】函数会从目标注册表项读取密文和私钥,经解密后再输出到第二个对话框中。由于密钥和机器是无关的,所以可以在 A 电脑上用测试程序完成加密动作,然后将目标注册表项导出到 B 电脑上用同样的测试程序完成解密动作。

public:
	afx_msg void OnBnClickedButtonEncrypt();
	afx_msg void OnBnClickedButtonDecrypt();	

private:
	void ShowError(const char* pszText);
	BOOL ReturnPublicKeyStorePrivateKey(BYTE** ppPublicKey, DWORD* pdwPublicKeyLength);
	BOOL RsaEncrypt(BYTE* pPublicKey, DWORD dwPublicKeyLength, BYTE* pData, DWORD& dwDataLength, DWORD dwBufferLength);
	BOOL RsaDecrypt(BYTE* pPrivateKey, DWORD dwProvateKeyLength, BYTE* pData, DWORD& dwDataLength);

为了完成以上描述的任务,例程封装了3个 private 函数:

  • 【ReturnPublicKeyStorePrivateKey】负责生成公钥和私钥,然后存储私钥,导出公钥;
  • 【RsaEncrypt】负责用公钥加密明文,并返回给调用方存储密文;
  • 【RsaDecrypt】负责用私钥解密密文,并输出;

【OnBnClickedButtonEncrypt】:

void CCryptoApiRsaMfcTestDlg::OnBnClickedButtonEncrypt()
{
	// Generate public and store private key into target register path
	BYTE* pData = NULL;
	DWORD dwBufferLength = 2048;

	pData = new BYTE[dwBufferLength];
	if (NULL == pData)
	{
		AfxMessageBox(_T("Create pData failure!"), MB_ICONERROR);
		return;
	}

	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_TOBE);
	CString strText;
	pEdit->GetWindowText(strText);

	int bufferSize = WideCharToMultiByte(CP_UTF8, 0, strText, -1, NULL, 0, NULL, NULL);
	if (bufferSize > 0)
	{
		char* pMultiByteText = new char[bufferSize];
		WideCharToMultiByte(CP_UTF8, 0, strText, -1, pMultiByteText, bufferSize, NULL, NULL);
		DWORD dwTextLength = strlen(pMultiByteText);

		if (dwTextLength <= dwBufferLength)
		{
			memcpy(pData, pMultiByteText, dwTextLength);
			pData[dwTextLength] = '\0';
		}
		else
		{
			AfxMessageBox(_T("dwTextLength > dwBufferLength!"), MB_ICONERROR);
			return;
		}

		delete[] pMultiByteText;
	}
	else
	{
		AfxMessageBox(_T("No input, bufferSize <= 0!"), MB_ICONERROR);
		return;
	}

	BYTE* pPublicKey = NULL;
	DWORD dwPublicKeyLength = 0;
	ReturnPublicKeyStorePrivateKey(&pPublicKey, &dwPublicKeyLength);

	// Use public key to encrypt input
	DWORD dwDataLength = 0;
	dwDataLength = 1 + ::lstrlenA((char*)pData);
	RsaEncrypt(pPublicKey, dwPublicKeyLength, pData, dwDataLength, dwBufferLength);

	// Store encrypted input into target register path
	CString strAppName = AfxGetAppName();
	CString strRegistryPath;
	strRegistryPath.Format(_T("SOFTWARE\\%s"), strAppName);
	LPCTSTR lpRegistryPath = strRegistryPath.GetBuffer();

	HKEY hKey;
	LONG result = RegCreateKeyEx(HKEY_CURRENT_USER, lpRegistryPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL);

	if (result == ERROR_SUCCESS) 
	{
		result = RegSetValueEx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值