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

📄 crypto.cpp

📁 使用Windows加密API的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}


BOOL CCrypto::
Initialize() const
	{
	BOOL	bSuccess	= TRUE;

	if( !m_hContext )		
		{
		bSuccess =  InitializeContainer();
		if( bSuccess )
			{
			bSuccess  = InitializeDigitalSignatureEngine();

			if( bSuccess )
				bSuccess = 	InitializeEncryptionEngine();

				//	If we failed to initialize digital signatures or encryption, then reset
			if( !bSuccess )
				{
				CryptReleaseContext( m_hContext, 0 );
				m_hContext = NULL;
				}
			}
		}
	return bSuccess;
	}


BOOL CCrypto::
InitializeContainer() const
	{
	USES_CONVERSION;
	BOOL	bSuccess = FALSE;
	int		nStringID= IDS_UNKNOWN_ERROR;

	ATLASSERT( !m_hContext );
	bSuccess = CryptAcquireContext( &m_hContext, 
									W2T(m_bstrContainerName.m_str), 
									MS_DEF_PROV, 
									PROV_RSA_FULL, 0 );
		
		//	Container doesn't exist - Possibly try to create a new container
	if( !bSuccess )
		{
		int nLastError = GetLastError();
		if( nLastError == NTE_BAD_KEYSET )
			{
				//	Creating the key container for the first time
			bSuccess = CryptAcquireContext( &m_hContext, 
											W2T(m_bstrContainerName.m_str), 
											MS_DEF_PROV, 
											PROV_RSA_FULL, CRYPT_NEWKEYSET );

			if( !bSuccess )
				nStringID = IDS_ERROR_INITIALIZATION_CREATE_NEW_CONTAINER_FAILED;
			}
		else
			nStringID = LookupCryptErrorStringID( nLastError );
		}

	if( !bSuccess )
		CRYPTO_OUTPUT_DEBUGSTRING( nStringID );

	return bSuccess;
	}


BOOL CCrypto::
InitializeDigitalSignatureEngine() const
	{
	BOOL		bSuccess = FALSE;
	HCRYPTKEY	hKey	 = NULL;
	int			nStringID= IDS_UNKNOWN_ERROR;

		//	Check the key pair for digital signatures
	if( !CryptGetUserKey( m_hContext, AT_SIGNATURE, &hKey ) )
		{
		if( GetLastError() == NTE_NO_KEY ) 
			{		
				// There is a container but no key - Create signature key pair
			if( !CryptGenKey( m_hContext, AT_SIGNATURE, 0, &hKey ) )
				nStringID = IDS_ERROR_INITIALIZATION_CREATE_DIGSIGKEYS;

			else
				bSuccess = TRUE;
			}
		else
			nStringID = IDS_ERROR_INITIALIZATION_CREATE_DIGSIGKEYS;
		}

		//	Key pair already available
	else
		bSuccess = TRUE;
	
	if( hKey )
		CryptDestroyKey( hKey );

	if( !bSuccess )
		CRYPTO_OUTPUT_DEBUGSTRING( nStringID );

	return bSuccess;
	}


BOOL CCrypto::
InitializeEncryptionEngine() const
	{
	BOOL		bSuccess = FALSE;
	HCRYPTKEY	hKey	 = NULL;
	int			nStringID= IDS_UNKNOWN_ERROR;

		//	Check the key pair for encryption
	if( !CryptGetUserKey( m_hContext, AT_KEYEXCHANGE, &hKey ) )
		{
		if( GetLastError() == NTE_NO_KEY ) 
			{		
				// There is a container but no key - Create an encryption key pair
			if( !CryptGenKey( m_hContext, AT_KEYEXCHANGE, 0, &hKey ) )
				nStringID = IDS_ERROR_INITIALIZATION_CREATE_ENCRYPTIONKEYS;

			else
				bSuccess = TRUE;
			}
		else
			nStringID = IDS_ERROR_INITIALIZATION_CREATE_ENCRYPTIONKEYS;
		}

		//	Key pair already available
	else
		bSuccess = TRUE;
	
	if( hKey )
		CryptDestroyKey( hKey );

	if( !bSuccess )
		CRYPTO_OUTPUT_DEBUGSTRING( nStringID );

	return bSuccess;
	}


void CCrypto::
ClearDigitalSignature()
	{
	SAFE_MALLOC_FREE( m_lpDigitalSignature );
	m_dwDigitalSignatureLen = 0;
	}


BOOL CCrypto::
WritePrivateKey(	FILE*		pDestination, 
					HCRYPTKEY&	hPrivateKey	)
	{
	BOOL		bSuccess	= FALSE;
	DWORD		dwBlobLen	= 0;
	LPBYTE		lpPrivateKey= NULL;

	ATLASSERT( pDestination	!= NULL );
	
		//	Get a private key
	hPrivateKey = GeneratePrivateKey( &lpPrivateKey, &dwBlobLen, FILE_ENCRYPT_ALGORITHM );

		//	If we succeeded in getting a private key...
	if(  lpPrivateKey )
		{
			//	Write the size of the private key to the destination file
		if( fwrite(  &dwBlobLen, sizeof(dwBlobLen), 1, pDestination ) )
			{
				//	Write the private key (encrypted) to the destination file
			if( fwrite( lpPrivateKey, sizeof(BYTE), dwBlobLen, pDestination ) == dwBlobLen )
				bSuccess = TRUE;
			}
		}

	SAFE_MALLOC_FREE( lpPrivateKey );
	return bSuccess;
	}


BOOL CCrypto::
ReadPrivateKey( FILE* pSrcFile, HCRYPTKEY& hPrivateKey ) const
	{
	BOOL		bSuccess		= FALSE;
	DWORD		dwKeySize		= 0;
	LPBYTE		lpPrivateKey	= NULL;

	ATLASSERT( pSrcFile		!= NULL );

		//	Read in the key size
	if( fread( &dwKeySize, sizeof(DWORD), 1, pSrcFile ) )
		{
			//	Allocate room to hold the private key
		lpPrivateKey = (LPBYTE)malloc( sizeof(BYTE)*dwKeySize );
		ATLASSERT( lpPrivateKey != NULL );
		if( lpPrivateKey )
			{
				//	Read in the private key
			if( fread(	lpPrivateKey, 
						sizeof(BYTE), 
						dwKeySize, 
						pSrcFile ) == dwKeySize )
				{
					//	Import the private key into the CSP
				bSuccess = CryptImportKey(  m_hContext, 
											lpPrivateKey, 
											dwKeySize, 0, 0, 
											&hPrivateKey		);
				}
			}				
		}
	SAFE_MALLOC_FREE( lpPrivateKey );
	return bSuccess;
	}


BOOL CCrypto::
WriteFileFormatVersion( FILE* pDestination ) const
	{
	DWORD	dwFileFormat = FILE_BINARY_FORMAT_VERSION;
	
	ATLASSERT( pDestination != NULL );

		//	Stamp the file with the version header
	return( fwrite( &dwFileFormat, sizeof(DWORD), 1, pDestination ) );
	}


BOOL CCrypto::
ReadFileFormatVersion( FILE* pSrc ) const
	{
	BOOL	bSuccess	 = FALSE;
	DWORD	dwFileFormat = INVALID_FORMAT_VERSION;
	
	ATLASSERT( pSrc != NULL );
	if( fread( &dwFileFormat, sizeof(DWORD), 1, pSrc ) )
		{
		ATLASSERT( dwFileFormat == FILE_BINARY_FORMAT_VERSION );
		if( dwFileFormat == FILE_BINARY_FORMAT_VERSION )
			bSuccess = TRUE;
		}	
	return bSuccess;
	}


HCRYPTKEY CCrypto::
GeneratePrivateKey( LPBYTE*	lpPrivateKeyBlob, 
					LPDWORD lpdwBlobSize,
					int		enumAlgorithm		) 
	{
	HCRYPTKEY	hPrivateKey = NULL;
	HCRYPTKEY	hPublicKey  = NULL;

		//	Generate the private key
	ClearDigitalSignature();
	if( Initialize() &&
		CryptGenKey( m_hContext, 
					 enumAlgorithm, 
					 CRYPT_EXPORTABLE, &hPrivateKey ) )
		{
			// Get handle to the encrypter's exchange public key 
		if( CryptGetUserKey( m_hContext, AT_KEYEXCHANGE, &hPublicKey ) )
			{
				// Determine size of the key blob
			if( CryptExportKey( hPrivateKey, 
								hPublicKey, 
								SIMPLEBLOB, 
								0, NULL, 
								lpdwBlobSize ) )
				{
				(*lpPrivateKeyBlob) = (LPBYTE)malloc( sizeof(BYTE) * (*lpdwBlobSize) );
				ATLASSERT( lpPrivateKeyBlob != NULL );

				if( lpPrivateKeyBlob )
						// Encrypt and export private key 
					CryptExportKey( hPrivateKey, 
						 			hPublicKey, 
									SIMPLEBLOB, 
									0, 
									(*lpPrivateKeyBlob), 
									lpdwBlobSize		);
				}
			}
		}

	if( hPublicKey )
		CryptDestroyKey( hPublicKey );

	return hPrivateKey;
	}


BOOL CCrypto::
DigitallySignHash( HCRYPTHASH hHash )
	{
	BOOL	bSuccess	= FALSE;

	ATLASSERT( hHash );
	
		//	Clear existing signature
	ClearDigitalSignature();
	
		//	Determine the length of the digital signature
	if( CryptSignHash( hHash, 
					   AT_SIGNATURE, NULL, 
					   0, NULL, &m_dwDigitalSignatureLen ) )
		{
		ATLASSERT( m_lpDigitalSignature == NULL );
		m_lpDigitalSignature = (LPBYTE)malloc( m_dwDigitalSignatureLen + 1 );
		if( m_lpDigitalSignature )
				//	Sign the original (decrypted) data 
			bSuccess = CryptSignHash(	hHash, 
										AT_SIGNATURE, NULL, 0, 
										m_lpDigitalSignature, 
										&m_dwDigitalSignatureLen );
		}
	return bSuccess;
	}


HRESULT CCrypto::
Base64FileHelper( BSTR		bstrSrc, 
				  VARIANT	varDestination, 
				  BOOL		bEncode				) const
	{
	USES_CONVERSION;
	USES_CHECKHR_MSG( IID_ICrypto );
	HRESULT		hr						= S_OK;
	LPBYTE		lpData[ FILE_READBYTES ]= {0}; 
	FILE*		pSrcFile				= NULL;
	FILE*		pDestinationFile		= NULL;
	HGLOBAL		hEncodedBytes			= NULL;
	BOOL		bSrcIsDestination		= PARAM_IS_MISSING( varDestination );
	try
		{
		CBase64Helper	Base64;

		pSrcFile = fopen( W2A(bstrSrc), "rb" );

			//	Open destination with intentions of destroying existing contents
		if( pSrcFile )
			pDestinationFile	= bSrcIsDestination ? 
										fopen( FILE_INTERMEDIATE_FILENAME,  "w+b" ) :
										fopen( W2A(varDestination.bstrVal), "w+b" );

		ATLASSERT( pSrcFile			!= NULL );
		ATLASSERT( pDestinationFile != NULL );

			//	Make sure the files opened
		if( pSrcFile			== NULL ||
			pDestinationFile	== NULL		)
			nStringID = IDS_ERROR_ENCODEDFILE_FILEOPENFAILED,
			THROW_HRESULT( E_FAIL );

		do
			{
				// Read up to FILE_READBYTES_BLOCKSIZE bytes from the source file
			DWORD dwEncoded = 0;
			DWORD dwCount	= fread(	lpData, 
										sizeof(BYTE), 
										FILE_READBYTES, 
										pSrcFile );
			
			if( ferror( pSrcFile ) )
				nStringID = IDS_ERROR_ENCODEDFILE_FILEIO,
				THROW_HRESULT( E_FAIL );

				//	Encode or decode the bits
			dwEncoded = bEncode ? Base64.Base64Encoder( (LPBYTE)lpData, dwCount, &hEncodedBytes ) :
								  Base64.Base64Decoder( (LPBYTE)lpData, dwCount, &hEncodedBytes );
			
				// Write encoded/decoded data to the destination file
			fwrite( GlobalLock(hEncodedBytes), 
					sizeof(BYTE), 
					dwEncoded, 
					pDestinationFile ); 
			GlobalFree( hEncodedBytes );

			if( ferror( pDestinationFile ) )
				nStringID = IDS_ERROR_ENCODEDFILE_FILEIO,
				THROW_HRESULT( E_FAIL );
			}
		while( !feof(pSrcFile) );
		fflush( pDestinationFile );
		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}

	if( pSrcFile )
		fclose( pSrcFile );

	if( pDestinationFile )
		fclose( pDestinationFile );

		//	Caller wants to overwrite src - Copy Destination to Source
	if( SUCCEEDED(hr) && 
		bSrcIsDestination )
		{
			//	CopyFile fails if file is readonly
		SetFileAttributes( W2T(bstrSrc), FILE_ATTRIBUTE_NORMAL );
		if( !CopyFile( A2T(FILE_INTERMEDIATE_FILENAME), W2T(bstrSrc), FALSE ) )
			hr = Error( IDS_ERROR_DECRYPT_COPYDESTINATIONTOSOURCE_FAILED,
						IID_ICrypto, E_FAIL );
		}

		//	Delete the intermediate file
	_unlink( FILE_INTERMEDIATE_FILENAME );

	return hr;
	}


int CCrypto::
LookupCryptErrorStringID( int nLastError ) const
	{
	int nStringID;

	switch( nLastError )
		{
		case ERROR_NOT_ENOUGH_MEMORY:
		case NTE_NO_MEMORY:
			nStringID = IDS_ERROR_OUTOFMEMORY;
			break;
		case NTE_BAD_FLAGS:
			nStringID = IDS_ERROR_INITIALIZE_NTE_BAD_FLAGS;
			break;\
		case NTE_BAD_KEYSET_PARAM:
			nStringID = IDS_ERROR_INITIALIZE_NTE_BAD_KEYSET_PARAM;
			break;
		case NTE_BAD_PROV_TYPE:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_BAD_PROV_TYPE;
			break;
		case NTE_BAD_SIGNATURE:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_BAD_SIGNATURE;
			break;
		case NTE_EXISTS:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_EXISTS;
			break;
		case NTE_KEYSET_ENTRY_BAD:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_KEYSET_ENTRY_BAD;
			break;
		case NTE_KEYSET_NOT_DEF:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_KEYSET_NOT_DEF;
			break;
		case NTE_PROV_DLL_NOT_FOUND:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_PROV_DLL_NOT_FOUND;
			break;
		case NTE_PROV_TYPE_ENTRY_BAD:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_PROV_TYPE_ENTRY_BAD;
			break;
		case NTE_PROV_TYPE_NO_MATCH:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_PROV_TYPE_NO_MATCH;
			break;
		case NTE_PROV_TYPE_NOT_DEF:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_PROV_TYPE_NOT_DEF;
			break;
		case NTE_PROVIDER_DLL_FAIL: 
			nStringID = IDS_ERROR_INITIALIZATION_NTE_PROVIDER_DLL_FAIL;					
			break;
		case NTE_SIGNATURE_FILE_BAD:
			nStringID = IDS_ERROR_INITIALIZATION_NTE_SIGNATURE_FILE_BAD;
			break;
		default:
			nStringID = IDS_UNKNOWN_ERROR;
			break;
		}

	return nStringID;
	}

⌨️ 快捷键说明

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