⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypto.cpp

📁 客户端与服务器的加密验证,用vc开发,只是一个例子,只作参考.
💻 CPP
字号:
#include "StdAfx.h"
#include ".\crypto.h"

CCrypto::CCrypto(void)
{
	hCryptProv = NULL;	
	hPublicKey = NULL;
	hXchgKey = NULL;
	hKey = NULL;

	pbSessionKeyBlob = NULL;
	pbPublicKeyBlob = NULL;
}

CCrypto::~CCrypto(void)
{
}

BOOL CCrypto::GetCSP(LPCTSTR strUserName)
{
	if (hCryptProv != NULL) return TRUE;

	if(CryptAcquireContext(
		&hCryptProv,               
		strUserName,                  
		MS_DEF_RSA_SCHANNEL_PROV,               
		PROV_RSA_SCHANNEL,             
		0))                        
	{
		return TRUE;
	}
	else
	{ 
		if (GetLastError() == NTE_BAD_KEYSET)
		{
			if(CryptAcquireContext(
				&hCryptProv, 
				strUserName, 
				MS_DEF_RSA_SCHANNEL_PROV,
				PROV_RSA_SCHANNEL, 
				CRYPT_NEWKEYSET)) 
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}
		else
		{
			return FALSE;
		}
	} 
}

void CCrypto::ReleaseCSP(void)
{
	if (hCryptProv != NULL)	
		CryptReleaseContext(hCryptProv,0);
	hCryptProv = NULL;
}


BOOL CCrypto::GetRSAKey(void)
{
	if (pbPublicKeyBlob != NULL) return TRUE;

	if(!CryptGenKey(
		hCryptProv, 
		CALG_RSA_KEYX, 
		(512<<16)|CRYPT_EXPORTABLE, 
		&hXchgKey))
	{
		DWORD dwErrorCode = GetLastError();
		return FALSE;
	}

	BOOL bSuccess = CryptExportKey(hXchgKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyBlobLen);
	if (!bSuccess) 
	{	
		CryptDestroyKey(hXchgKey);
		hXchgKey = NULL;
		return FALSE;
	}
	pbPublicKeyBlob = (PBYTE)malloc(dwPublicKeyBlobLen);
	bSuccess = CryptExportKey(hXchgKey, NULL, PUBLICKEYBLOB, 0, pbPublicKeyBlob, &dwPublicKeyBlobLen);
	if (!bSuccess)	
	{
		free(pbPublicKeyBlob);
		pbPublicKeyBlob = NULL;
		CryptDestroyKey(hXchgKey);
		hXchgKey = NULL;
	}
	return TRUE;
}
BOOL CCrypto::GetSessionKey(void)
{
	if (pbSessionKeyBlob != NULL) return TRUE;

	if(!CryptGenKey(
		hCryptProv, 
		CALG_3DES, 
		CRYPT_EXPORTABLE, 
		&hKey))

	{
		DWORD dwErrorCode = GetLastError();
		return FALSE;
	}

	BOOL bSuccess = CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, NULL, &dwSessionKeyBlobLen);
	if (!bSuccess) 
	{
		DWORD dwErrorCode = GetLastError();
		ERROR_INVALID_HANDLE;	
		ERROR_INVALID_PARAMETER;
		ERROR_MORE_DATA;			
		NTE_BAD_FLAGS;			
		NTE_BAD_KEY	;			
		NTE_BAD_KEY_STATE	;	
		NTE_BAD_PUBLIC_KEY	;	
		NTE_BAD_TYPE 	;	
		NTE_BAD_UID		;		
		NTE_NO_KEY ;

		CryptDestroyKey(hKey);
		hKey = NULL;
		return FALSE;
	}

	pbSessionKeyBlob = (PBYTE)malloc(dwSessionKeyBlobLen);
	bSuccess = CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, pbSessionKeyBlob, &dwSessionKeyBlobLen);
	if (!bSuccess)	
	{
		free(pbSessionKeyBlob);
		pbSessionKeyBlob = NULL;
		CryptDestroyKey(hKey);
		hKey = NULL;
	}
	return TRUE;
}

void CCrypto::ReleaseKeys(void)
{
	if (hPublicKey != NULL)	CryptDestroyKey(hPublicKey);
	hPublicKey = NULL;
	if (hXchgKey != NULL)	CryptDestroyKey(hXchgKey);
	hXchgKey = NULL;
	if (hKey != NULL)	CryptDestroyKey(hKey);
	hKey = NULL;

	if (pbSessionKeyBlob != NULL)	free(pbSessionKeyBlob);
	pbSessionKeyBlob = NULL;
	if (pbPublicKeyBlob != NULL)	free(pbPublicKeyBlob);
	pbPublicKeyBlob = NULL;
}

BOOL CCrypto::ImportPublicKey(void)
{
	if (hPublicKey != NULL) return TRUE;

	BOOL bResult = CryptImportKey(hCryptProv, pbPublicKeyBlob, dwPublicKeyBlobLen, 0, 0, &hPublicKey);
	if (!bResult)	return FALSE;
}

BOOL CCrypto::ImportSessionKey(void)
{
	if (hKey != NULL) return TRUE;

	BOOL bResult = CryptImportKey(hCryptProv, pbSessionKeyBlob, dwSessionKeyBlobLen, hXchgKey, 0, &hKey);
	return bResult;
}

void CCrypto::CopyExportedPublicKeyFrom(const CCrypto & crypto)
{
	if (pbPublicKeyBlob != NULL) return;

	dwPublicKeyBlobLen = crypto.dwPublicKeyBlobLen;
	pbPublicKeyBlob = (PBYTE)malloc(dwPublicKeyBlobLen);
	memcpy(pbPublicKeyBlob, crypto.pbPublicKeyBlob, dwPublicKeyBlobLen);
}

void CCrypto::CopyExportedSessionKeyFrom(const CCrypto & crypto)
{
	if (pbSessionKeyBlob != NULL) return;

	dwSessionKeyBlobLen = crypto.dwSessionKeyBlobLen;
	pbSessionKeyBlob = (PBYTE)malloc(dwSessionKeyBlobLen);
	memcpy(pbSessionKeyBlob, crypto.pbSessionKeyBlob, dwSessionKeyBlobLen);
}

#define BLOCKLEN 24
BOOL CCrypto::EncryptData(CString & strData/*in out*/)
{
	CString strSrc;
	int nLenWant = (strData.GetLength()/BLOCKLEN)*BLOCKLEN;
	if (strData.GetLength()%BLOCKLEN != 0) nLenWant += BLOCKLEN;

	char *buffer = strSrc.GetBufferSetLength(nLenWant);
	ZeroMemory(buffer, nLenWant);
	memcpy(buffer, strData, strData.GetLength());

	DWORD dwCount = strData.GetLength();
	DWORD dwBufferLen = nLenWant;
	BOOL bResult = CryptEncrypt(hKey, 0, TRUE, 0, (BYTE *)buffer, &dwCount, dwBufferLen);

	DWORD dwErrorCode = 0;
	if (!bResult) dwErrorCode = GetLastError();

	strSrc.ReleaseBufferSetLength(dwCount);
	strData = strSrc;

	ERROR_INVALID_HANDLE	;//One of the parameters specifies an invalid handle. 
	ERROR_INVALID_PARAMETER ;//One of the parameters contains an invalid value. This is most often an invalid pointer. 
	NTE_BAD_ALGID			;//The hKey session key specifies an algorithm that this CSP does not support. 
	NTE_BAD_DATA			;//The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size. 
	NTE_BAD_FLAGS			;//The dwFlags parameter is nonzero. 
	NTE_BAD_HASH			;//The hHash parameter contains an invalid handle. 
	NTE_BAD_HASH_STATE		;//An attempt was made to add data to a hash object that is already marked "finished." 
	NTE_BAD_KEY				;//The hKey parameter does not contain a valid handle to a key. 
	NTE_BAD_LEN				;//The size of the output buffer is too small to hold the generated ciphertext. 
	NTE_BAD_UID				;//The CSP context that was specified when the key was created cannot be found. 
	NTE_DOUBLE_ENCRYPT		;//The application attempted to encrypt the same data twice. 
	NTE_FAIL				;//The function failed in some unexpected way. 
	NTE_NO_MEMORY			;//


	return bResult;
}

BOOL CCrypto::DecryptData(CString & strData/*in out*/)
{
	char *buffer = strData.GetBuffer();
	DWORD dwCount = strData.GetLength();

	BOOL bResult = CryptDecrypt(hKey, 0, TRUE, 0, (BYTE *)buffer, &dwCount);
	strData.ReleaseBuffer(dwCount);

	DWORD dwErrorCode = 0;
	if (!bResult) dwErrorCode = GetLastError();

	return bResult;
}

void CCrypto::PrintRSAKeyPair(CString & strPublicKey_e, CString & strPublicKey, CString & strPrivateKey)
{
	RSAPUBKEY *rsapubkey = (RSAPUBKEY *)(pbPublicKeyBlob + sizeof(PUBLICKEYSTRUC));
	BYTE *modulus = pbPublicKeyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
	strPublicKey_e.Format("0x%X", rsapubkey->pubexp);
	strPublicKey = "0x";
	for (int i=0; i<(rsapubkey->bitlen/8); i++)
	{
		CString strTmp;
		strTmp.Format("%02X ", modulus[i]);
		strPublicKey += strTmp;
	}

	PBYTE pbPrivateKeyBlob;		
	DWORD dwPrivateKeyBlobLen = 0;	

	BOOL bSuccess = CryptExportKey(hXchgKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyBlobLen);
	
	pbPrivateKeyBlob = (PBYTE)malloc(dwPrivateKeyBlobLen);
	bSuccess = CryptExportKey(hXchgKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKeyBlob, &dwPrivateKeyBlobLen);
	

	rsapubkey = (RSAPUBKEY *)(pbPrivateKeyBlob + sizeof(PUBLICKEYSTRUC));
	BYTE *privateExponent = pbPrivateKeyBlob + sizeof(PUBLICKEYSTRUC) + \
		sizeof(RSAPUBKEY) + rsapubkey->bitlen/8 + (rsapubkey->bitlen/16) * 5;

	strPrivateKey = "0x";
	for (int i=0; i<rsapubkey->bitlen/8; i++)
	{
		CString strTmp;
		strTmp.Format("%02X ", privateExponent[i]);
		strPrivateKey += strTmp;
	}

	free(pbPrivateKeyBlob);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -