zoukankan      html  css  js  c++  java
  • C/C++ 常用加解密算法收集

    网上收集的一些开发常用的加密解密算法的使用技巧,第三方库 Crypto++ 也可实现

    Base64加密1

    base64.h

    #ifndef base64_h
    #define base64_h
    
    #include <stdio.h>
    #include <Windows.h>
    #include <stdlib.h>
    
    #if __cplusplus
    extern "C"{
    #endif
    	// base64 转换表, 共64个
    	static const char base64_alphabet[] = {
    		'A', 'B', 'C', 'D', 'E', 'F', 'G',
    		'H', 'I', 'J', 'K', 'L', 'M', 'N',
    		'O', 'P', 'Q', 'R', 'S', 'T',
    		'U', 'V', 'W', 'X', 'Y', 'Z',
    		'a', 'b', 'c', 'd', 'e', 'f', 'g',
    		'h', 'i', 'j', 'k', 'l', 'm', 'n',
    		'o', 'p', 'q', 'r', 's', 't',
    		'u', 'v', 'w', 'x', 'y', 'z',
    		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    		'+', '/' };
    
    	// 解码时使用
    	static const unsigned char base64_suffix_map[256] = {
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
    		255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
    		52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
    		255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
    		7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
    		19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
    		255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
    		37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
    		49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    		255, 255, 255, 255 };
    
    	static char cmove_bits(unsigned char src, unsigned lnum, unsigned rnum) {
    		src <<= lnum; // src = src << lnum;
    		src >>= rnum; // src = src >> rnum;
    		return src;
    	}
    
    	int base64_encode(const char *indata, int inlen, char *outdata, int *outlen) {
    
    		int ret = 0; // return value
    		if (indata == NULL || inlen == 0) {
    			return ret = -1;
    		}
    
    		int in_len = 0; // 源字符串长度, 如果in_len不是3的倍数, 那么需要补成3的倍数
    		int pad_num = 0; // 需要补齐的字符个数, 这样只有2, 1, 0(0的话不需要拼接, )
    		if (inlen % 3 != 0) {
    			pad_num = 3 - inlen % 3;
    		}
    		in_len = inlen + pad_num; // 拼接后的长度, 实际编码需要的长度(3的倍数)
    		int out_len = in_len * 8 / 6; // 编码后的长度
    		char *p = outdata; // 定义指针指向传出data的首地址
    
    		//编码, 长度为调整后的长度, 3字节一组
    		for (int i = 0; i < in_len; i += 3) {
    			int value = *indata >> 2; // 将indata第一个字符向右移动2bit(丢弃2bit)
    			char c = base64_alphabet[value]; // 对应base64转换表的字符
    			*p = c; // 将对应字符(编码后字符)赋值给outdata第一字节
    
    			//处理最后一组(最后3字节)的数据
    			if (i == inlen + pad_num - 3 && pad_num != 0) {
    				if (pad_num == 1) {
    					*(p + 1) = base64_alphabet[(int)(cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4))];
    					*(p + 2) = base64_alphabet[(int)cmove_bits(*(indata + 1), 4, 2)];
    					*(p + 3) = '=';
    				}
    				else if (pad_num == 2) { // 编码后的数据要补两个 '='
    					*(p + 1) = base64_alphabet[(int)cmove_bits(*indata, 6, 2)];
    					*(p + 2) = '=';
    					*(p + 3) = '=';
    				}
    			}
    			else { // 处理正常的3字节的数据
    				*(p + 1) = base64_alphabet[cmove_bits(*indata, 6, 2) + cmove_bits(*(indata + 1), 0, 4)];
    				*(p + 2) = base64_alphabet[cmove_bits(*(indata + 1), 4, 2) + cmove_bits(*(indata + 2), 0, 6)];
    				*(p + 3) = base64_alphabet[*(indata + 2) & 0x3f];
    			}
    			p += 4;
    			indata += 3;
    		}
    		if (outlen != NULL) {
    			*outlen = out_len;
    		}
    		return ret;
    	}
    
    	int base64_decode(const char *indata, int inlen, char *outdata, int *outlen) {
    
    		int ret = 0;
    		if (indata == NULL || inlen <= 0 || outdata == NULL || outlen == NULL) {
    			return ret = -1;
    		}
    		if (inlen % 4 != 0) { // 需要解码的数据不是4字节倍数
    			return ret = -2;
    		}
    
    		int t = 0, x = 0, y = 0, i = 0;
    		unsigned char c = 0;
    		int g = 3;
    
    		while (indata[x] != 0) {
    			// 需要解码的数据对应的ASCII值对应base64_suffix_map的值
    			c = base64_suffix_map[indata[x++]];
    			if (c == 255) return -1;// 对应的值不在转码表中
    			if (c == 253) continue;// 对应的值是换行或者回车
    			if (c == 254) { c = 0; g--; }// 对应的值是'='
    			t = (t << 6) | c; // 将其依次放入一个int型中占3字节
    			if (++y == 4) {
    				outdata[i++] = (unsigned char)((t >> 16) & 0xff);
    				if (g > 1) outdata[i++] = (unsigned char)((t >> 8) & 0xff);
    				if (g > 2) outdata[i++] = (unsigned char)(t & 0xff);
    				y = t = 0;
    			}
    		}
    		if (outlen != NULL) {
    			*outlen = i;
    		}
    		return ret;
    	}
    #if __cplusplus
    }
    #endif
    
    #endif /* base64_h */
    

    main.c

    #include "base64.h"
    
    int main(int argc, const char * argv[])
    {
    	char str1[] = "https://www.baidu.com";
    	char str3[30] = { 0 };
    	char str2[30] = { 0 };
    	int len = 0;
    	
    	base64_encode(str1, (int)strlen(str1), str2, &len);
    	printf("加密后: %s 长度: %d\n", str2, len);
    
    	base64_decode(str2, (int)strlen(str2), str3, &len);
    	printf("解密后: %s 长度: %d\n", str3, len);
    
    	system("pause");
    	return 0;
    }
    

    Base64加密2

    #include <string.h>
    
    #define OK 0
    #define ERR -1
    #define DECODE_SRC_LEN  4
    #define DECODE_RET_LEN  3
    #define BASE_SRC_LEN  3
    #define BASE_DST_LEN  4
    
    /*
    A~Z,a~z,0~9,+/
    */
    char Base64ToAsc(char c)
    {
    	if (c >= 'A' && c <= 'Z')
    	{
    		return c - 'A';
    	}
    	else if (c >= 'a' && c <= 'z')
    	{
    		return 26 + c - 'a';
    	}
    	else if (c >= '0' && c <= '9')
    	{
    		return 52 + c - '0';
    	}
    	else if (c == '+')
    	{
    		return 62;
    	}
    	else if (c == '/')
    	{
    		return 63;
    	}
    	else
    	{
    		return c;
    	}
    
    }
    
    //szSrc[] 长度必然能被 4 整除
    int DecodeBase64(char szRet[], char szSrc[], int iLen)
    {
    	int  iLoop = iLen / DECODE_SRC_LEN;
    	int  iSrcOffset;
    	int  iRetOffset;
    	int  i;
    	int  j;
    	char szTmp[DECODE_SRC_LEN] = { 0 };
    
    
    	for (i = 0; i < iLoop; i++)
    	{
    		iSrcOffset = i * DECODE_SRC_LEN;
    		iRetOffset = i * DECODE_RET_LEN;
    
    		for (j = 0; j < DECODE_SRC_LEN; j++)
    		{
    			szTmp[j] = Base64ToAsc(szSrc[iSrcOffset + j]);
    		}
    
    		szRet[iRetOffset] = (szTmp[0] << 2) | (szTmp[1] >> 4);
    
    		if (szTmp[2] == '=')
    		{
    			szRet[iRetOffset + 1] = 0;
    			break;
    		}
    		szRet[iRetOffset + 1] = (szTmp[1] << 4) | (szTmp[2] >> 2);
    
    		if (szTmp[3] == '=')
    		{
    			szRet[iRetOffset + 2] = 0;
    			break;
    		}
    		szRet[iRetOffset + 2] = (szTmp[2] << 6) | (szTmp[3]);
    	}
    	return OK;
    }
    
    typedef struct Base64Cov
    {
    	unsigned int sect1 : 6;
    	unsigned int sect2 : 6;
    	unsigned int sect3 : 6;
    	unsigned int sect4 : 6;
    }BASE64COV_S;
    
    /*
    30~25  映射到 A~Z ,
    26~51 映射到 a~z ,
    52~61映射到 0~9,
    62映射到+,
    63 映射到
    */
    char g_acBaseMap[] = "ABCD...Za...z0..9+/";
    
    char ConvertToBase64(char c)
    {
    	if (c < 26)
    	{
    		return 'A' + c;
    	}
    	else if (c < 52)
    	{
    		return 'a' + (c - 26);
    	}
    	else if (c < 62)
    	{
    		return '0' + (c - 52);
    	}
    	else if (c == 62)
    	{
    		return '+';
    	}
    	else
    	{
    		return '/';
    	}
    }
    
    //把 szSrc 每3个字符编码成 4个字符
    int  EncodeBase64(char szRet[], char szSrc[], int iSrcLen)
    {
    	BASE64COV_S  *pBase;
    	char szTmp[BASE_SRC_LEN] = { 'a', 'b', 'c' };
    	int iLoop = iSrcLen / BASE_SRC_LEN;
    	int iSrcOffSet;
    	int iRetOffSet;
    	int i;
    
    
    	for (i = 0; i < iLoop; i++)
    	{
    		//3个字符逆序放入szTmp
    		iSrcOffSet = i*BASE_SRC_LEN;
    		iRetOffSet = i*BASE_DST_LEN;
    
    		szTmp[0] = *(szSrc + iSrcOffSet + 2);
    		szTmp[1] = *(szSrc + iSrcOffSet + 1);
    		szTmp[2] = *(szSrc + iSrcOffSet);
    
    		pBase = (BASE64COV_S  *)szTmp;
    		szRet[i*BASE_DST_LEN] = ConvertToBase64(pBase->sect4);
    		szRet[i*BASE_DST_LEN + 1] = ConvertToBase64(pBase->sect3);
    		szRet[i*BASE_DST_LEN + 2] = ConvertToBase64(pBase->sect2);
    		szRet[i*BASE_DST_LEN + 3] = ConvertToBase64(pBase->sect1);
    	}
    
    	if (iSrcLen % BASE_SRC_LEN == 1)
    	{
    		iSrcOffSet += BASE_SRC_LEN;
    		iRetOffSet += BASE_DST_LEN;
    
    		szTmp[0] = 0;
    		szTmp[1] = 0;
    		szTmp[2] = *(szSrc + iSrcOffSet);
    
    		pBase = (BASE64COV_S  *)szTmp;
    		szRet[i*BASE_DST_LEN] = ConvertToBase64(pBase->sect4);
    		szRet[i*BASE_DST_LEN + 1] = ConvertToBase64(pBase->sect3);
    		szRet[i*BASE_DST_LEN + 2] = '=';
    		szRet[i*BASE_DST_LEN + 3] = '=';
    	}
    	else if (iSrcLen % BASE_SRC_LEN == 2)
    	{
    		iSrcOffSet += BASE_SRC_LEN;
    		iRetOffSet += BASE_DST_LEN;
    
    		szTmp[0] = 0;
    		szTmp[1] = *(szSrc + iSrcOffSet + 1);
    		szTmp[2] = *(szSrc + iSrcOffSet);
    
    		pBase = (BASE64COV_S  *)szTmp;
    		szRet[i*BASE_DST_LEN] = ConvertToBase64(pBase->sect4);
    		szRet[i*BASE_DST_LEN + 1] = ConvertToBase64(pBase->sect3);
    		szRet[i*BASE_DST_LEN + 2] = ConvertToBase64(pBase->sect2);
    		szRet[i*BASE_DST_LEN + 3] = '=';
    	}
    
    	return OK;
    }
    
    #define TEST_LEN 100
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char szSrc[] = "abcde";
    	char szMid[TEST_LEN] = { 0 };
    	char szRet[TEST_LEN] = { 0 };
    
    	printf("SRC :%s\n", szSrc);
    	EncodeBase64(szMid, szSrc, strlen(szSrc));
    	printf("Encode:%s\n", szMid);
    	DecodeBase64(szRet, szMid, strlen(szMid));
    	printf("Decode:%s\n", szRet);
    
    	getchar();
    	return 0;
    }
    

    AES 加解密

    #include <stdio.h>
    #include <Windows.h>
    
    // AES加密
    BOOL AesEncrypt(BYTE *pPassword, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
    {
    	BOOL bRet = TRUE;
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTHASH hCryptHash = NULL;
    	HCRYPTKEY hCryptKey = NULL;
    	DWORD dwPasswordLength = lstrlen((char *)pPassword);
    
    	do
    	{
    		// 获取CSP句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    		// 创建HASH对象
    		bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
    		// 对密钥进行HASH计算
    		bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0);
    		// 使用HASH来生成密钥
    		bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
    		// 加密数据
    		bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
    	} while (FALSE);
    
    	// 关闭释放
    	if (hCryptKey || hCryptHash || hCryptProv)
    	{
    		::CryptDestroyKey(hCryptKey);
    		::CryptDestroyHash(hCryptHash);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    // AES解密
    BOOL AesDecrypt(BYTE *pPassword, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
    {
    	BOOL bRet = TRUE;
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTHASH hCryptHash = NULL;
    	HCRYPTKEY hCryptKey = NULL;
    	DWORD dwPasswordLength = lstrlen((char *)pPassword);
    
    	do
    	{
    		// 获取CSP句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    		// 创建HASH对象
    		bRet = ::CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash);
    		// 对密钥进行HASH计算
    		bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0);
    		// 使用HASH来生成密钥
    		bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, CRYPT_EXPORTABLE, &hCryptKey);
    		// 解密数据
    		bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength);
    	} while (FALSE);
    	// 关闭释放
    	if (hCryptKey || hCryptHash || hCryptProv)
    	{
    		::CryptDestroyKey(hCryptKey);
    		::CryptDestroyHash(hCryptHash);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    int main(int argc, char *argv[])
    {
    	BYTE pData[MAX_PATH] = { 0 };
    	DWORD dwDataLength = 0;
    	char *Msg = "hello lyshark !";
    
    	::lstrcpy((char *)pData, Msg);
    	dwDataLength = 1 + ::lstrlen((char *)pData);
    
    	// AES 加密
    	AesEncrypt((BYTE *)"123321", pData, dwDataLength, MAX_PATH);
    	printf("AES 加密长度: %d 加密后: %s \n", dwDataLength,pData);
    
    	// AES 解密
    	AesDecrypt((BYTE *)"123321", pData, dwDataLength, MAX_PATH);
    	printf("AES 解密长度: %d 解密后: %s \n", dwDataLength, pData);
    
    	system("pause");
    	return 0;
    }
    
    

    md5/SHA256/SHA512

    #include <Windows.h>
    
    BOOL GetFileData(char *pszFilePath, BYTE **ppFileData, DWORD *pdwFileDataLength)
    {
    	BOOL bRet = TRUE;
    	BYTE *pFileData = NULL;
    	DWORD dwFileDataLength = 0;
    	HANDLE hFile = NULL;
    	DWORD dwTemp = 0;
    
    	do
    	{
    		hFile = ::CreateFile(pszFilePath, GENERIC_READ | GENERIC_WRITE,
    			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
    			FILE_ATTRIBUTE_ARCHIVE, NULL);
    		if (INVALID_HANDLE_VALUE == hFile)
    		{
    			bRet = FALSE;
    			break;
    		}
    		dwFileDataLength = ::GetFileSize(hFile, NULL);
    		pFileData = new BYTE[dwFileDataLength];
    		if (NULL == pFileData)
    		{
    			bRet = FALSE;
    			break;
    		}
    		::RtlZeroMemory(pFileData, dwFileDataLength);
    
    		::ReadFile(hFile, pFileData, dwFileDataLength, &dwTemp, NULL);
    
    		*ppFileData = pFileData;
    		*pdwFileDataLength = dwFileDataLength;
    	} while (FALSE);
    
    	if (hFile)
    	{
    		::CloseHandle(hFile);
    	}
    	return bRet;
    }
    
    BOOL CalculateHash(BYTE *pData, DWORD dwDataLength, ALG_ID algHashType, BYTE **ppHashData, DWORD *pdwHashDataLength)
    {
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTHASH hCryptHash = NULL;
    	BYTE *pHashData = NULL;
    	DWORD dwHashDataLength = 0;
    	DWORD dwTemp = 0;
    	BOOL bRet = FALSE;
    	do
    	{
    		// 获得指定CSP的密钥容器的句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    		// 创建一个HASH对象, 指定HASH算法
    		bRet = ::CryptCreateHash(hCryptProv, algHashType, NULL, NULL, &hCryptHash);
    		// 计算HASH数据
    		bRet = ::CryptHashData(hCryptHash, pData, dwDataLength, 0);
    		// 获取HASH结果的大小
    		dwTemp = sizeof(dwHashDataLength);
    		bRet = ::CryptGetHashParam(hCryptHash, HP_HASHSIZE, (BYTE *)(&dwHashDataLength), &dwTemp, 0);
    		// 申请内存
    		pHashData = new BYTE[dwHashDataLength];
    		::RtlZeroMemory(pHashData, dwHashDataLength);
    		// 获取HASH结果数据
    		bRet = ::CryptGetHashParam(hCryptHash, HP_HASHVAL, pHashData, &dwHashDataLength, 0);
    		// 返回数据
    		*ppHashData = pHashData;
    		*pdwHashDataLength = dwHashDataLength;
    	} while (FALSE);
    
    	// 释放关闭
    	if (FALSE == bRet)
    	{
    		if (pHashData)
    		{
    			delete[]pHashData;
    			pHashData = NULL;
    		}
    	}
    	if (hCryptHash || hCryptProv)
    	{
    		::CryptDestroyHash(hCryptHash);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    
    int main(int argc, char* argv[])
    {
    	BYTE *pData = NULL;
    	DWORD dwDataLength = 0;
    	BYTE *pHashData = NULL;
    	DWORD dwHashDataLength = 0;
    	
    	// 读取文件数据
    	GetFileData("C:\\nc.exe", &pData, &dwDataLength);
    
    	// MD5
    	CalculateHash(pData, dwDataLength, CALG_MD5, &pHashData, &dwHashDataLength);
    
    	for (DWORD x = 0; x < dwHashDataLength; x++)
    		printf("%x", pHashData[x]);
    	printf("\n");
    
    	// SHA256
    	CalculateHash(pData, dwDataLength, CALG_SHA_256, &pHashData, &dwHashDataLength);
    	for (DWORD x = 0; x < dwHashDataLength; x++)
    		printf("%x", pHashData[x]);
    
    	delete[]pHashData;
    	pHashData = NULL;
    
    	system("pause");
    	return 0;
    }
    

    RSA

    // 生成公钥和私钥
    BOOL GenerateKey(BYTE **ppPublicKey, DWORD *pdwPublicKeyLength, BYTE **ppPrivateKey, DWORD *pdwPrivateKeyLength)
    {
    	BOOL bRet = TRUE;
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTKEY hCryptKey = NULL;
    	BYTE *pPublicKey = NULL;
    	DWORD dwPublicKeyLength = 0;
    	BYTE *pPrivateKey = NULL;
    	DWORD dwPrivateKeyLength = 0;
    
    	do
    	{
    		// 获取CSP句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
    		// 生成公私密钥对
    		bRet = ::CryptGenKey(hCryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hCryptKey);
    		// 获取公钥密钥的长度和内容
    		bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLength);
    
    		pPublicKey = new BYTE[dwPublicKeyLength];
    		::RtlZeroMemory(pPublicKey, dwPublicKeyLength);
    		bRet = ::CryptExportKey(hCryptKey, NULL, PUBLICKEYBLOB, 0, pPublicKey, &dwPublicKeyLength);
    
    		// 获取私钥密钥的长度和内容
    		bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyLength);
    
    		pPrivateKey = new BYTE[dwPrivateKeyLength];
    		::RtlZeroMemory(pPrivateKey, dwPrivateKeyLength);
    		bRet = ::CryptExportKey(hCryptKey, NULL, PRIVATEKEYBLOB, 0, pPrivateKey, &dwPrivateKeyLength);
    
    		// 返回数据
    		*ppPublicKey = pPublicKey;
    		*pdwPublicKeyLength = dwPublicKeyLength;
    		*ppPrivateKey = pPrivateKey;
    		*pdwPrivateKeyLength = dwPrivateKeyLength;
    
    	} while (FALSE);
    
    	// 释放关闭
    	if (hCryptKey || hCryptProv)
    	{
    		::CryptDestroyKey(hCryptKey);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    // 公钥加密数据
    BOOL RsaEncrypt(BYTE *pPublicKey, DWORD dwPublicKeyLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
    {
    	BOOL bRet = TRUE;
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTKEY hCryptKey = NULL;
    	do
    	{
    		// 获取CSP句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
    		// 导入公钥
    		bRet = ::CryptImportKey(hCryptProv, pPublicKey, dwPublicKeyLength, NULL, 0, &hCryptKey);
    		// 加密数据
    		bRet = ::CryptEncrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength, dwBufferLength);
    	} while (FALSE);
    
    	// 释放并关闭
    	if (hCryptKey || hCryptProv)
    	{
    		::CryptDestroyKey(hCryptKey);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    // 私钥解密数据
    BOOL RsaDecrypt(BYTE *pPrivateKey, DWORD dwProvateKeyLength, BYTE *pData, DWORD &dwDataLength)
    {
    	BOOL bRet = TRUE;
    	HCRYPTPROV hCryptProv = NULL;
    	HCRYPTKEY hCryptKey = NULL;
    	do
    	{
    		// 获取CSP句柄
    		bRet = ::CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
    		// 导入私钥
    		bRet = ::CryptImportKey(hCryptProv, pPrivateKey, dwProvateKeyLength, NULL, 0, &hCryptKey);
    		// 解密数据
    		bRet = ::CryptDecrypt(hCryptKey, NULL, TRUE, 0, pData, &dwDataLength);
    	} while (FALSE);
    
    	// 释放并关闭
    	if (hCryptKey || hCryptProv)
    	{
    		::CryptDestroyKey(hCryptKey);
    		::CryptReleaseContext(hCryptProv, 0);
    	}
    	return bRet;
    }
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	BYTE *pPublicKey = NULL;
    	DWORD dwPublicKeyLength = 0;
    	BYTE *pPrivateKey = NULL;
    	DWORD dwPrivateKeyLength = 0;
    	BYTE *pData = NULL;
    	DWORD dwDataLength = 0;
    	DWORD dwBufferLength = 4096;
    	DWORD i = 0;
    
    	pData = new BYTE[dwBufferLength];
    	if (NULL == pData)
    	{
    		return 1;
    	}
    	::RtlZeroMemory(pData, dwBufferLength);
    	::lstrcpy((char *)pData, "hello lyshark");
    	dwDataLength = 1 + ::lstrlen((char *)pData);
    	
    	// 生成公钥和私钥
    	GenerateKey(&pPublicKey, &dwPublicKeyLength, &pPrivateKey, &dwPrivateKeyLength);
    	printf("Public Key[%d]\n", dwPublicKeyLength);
    	for (i = 0; i < dwPublicKeyLength; i++)
    		printf("%.2x", pPublicKey[i]);
    	printf("\n");
    
    	printf("Private Key[%d]\n", dwPrivateKeyLength);
    	for (i = 0; i < dwPrivateKeyLength; i++)
    		printf("%.2x", pPrivateKey[i]);
    	printf("\n\n");
    
    
    	// 公钥加密
    	RsaEncrypt(pPublicKey, dwPublicKeyLength, pData, dwDataLength, dwBufferLength);
    	printf("RSA Encrypt[%d]\n", dwDataLength);
    	for (i = 0; i < dwDataLength; i++)
    		printf("%x", pData[i]);
    	printf("\n\n");
    
    	// 私钥解密
    	RsaDecrypt(pPrivateKey, dwPrivateKeyLength, pData, dwDataLength);
    	printf("RSA Decrypt[%d] %s \n", dwDataLength,pData);
    	printf("\n\n");
    
    	// 释放
    	if (pData)
    	{
    		delete[]pData;
    		pData = NULL;
    	}
    	if (pPrivateKey)
    	{
    		delete[]pPrivateKey;
    		pPrivateKey = NULL;
    	}
    	if (pPublicKey)
    	{
    		delete[]pPublicKey;
    		pPublicKey = NULL;
    	}
    
    	system("pause");
    	return 0;
    }
    
    文章出处:https://www.cnblogs.com/LyShark/p/13052469.html
    版权声明:本博客文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!

    如果您恶意转载本人文章并被本人发现,则您的整站文章,将会变为我的原创作品,请相互尊重 !
    转载规范 点击阅读 如果您转载本人文章,则视为您默认同意此规范约定。
  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/LyShark/p/13052469.html
Copyright © 2011-2022 走看看