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

📄 crypto.cpp

📁 使用Windows加密API的例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
									&dwCount	 ) )
					nStringID = IDS_ERROR_DECRYPT_DECRYPTION_FAILED,
					THROW_HRESULT( E_FAIL );
				
					// Write decrypted data to the destination file
				fwrite( lpData, sizeof(BYTE), dwCount, pDestinationFile ); 
				if( ferror( pDestinationFile ) )
					nStringID = IDS_ERROR_DECRYPT_WRITETODESTINATION_FAILED,
					THROW_HRESULT( E_FAIL );
				} 
			while( !feof( pSrcFile ) ); 
			fflush( pDestinationFile );

				//	Determine the length of the digital signature
			if( !DigitallySignHash( hDigSigHash ) )
				nStringID = IDS_ERROR_DECRYPT_SIGNHASH_FAILED,
				THROW_HRESULT( E_FAIL );
		 	}
		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}
      
		///////////////////////////////////////////////////////////////////////
		//	Cleanup
	if( hPrivateKey )
		CryptDestroyKey( hPrivateKey );

	if( pSrcFile )
		fclose( pSrcFile );

	if( pDestinationFile )
		fclose( pDestinationFile );

	SAFE_MALLOC_FREE( lpData );

	if( hDigSigHash )
		CryptDestroyHash( hDigSigHash );

		//	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 - if it exists
	_unlink( FILE_INTERMEDIATE_FILENAME );

	return hr;
	}


STDMETHODIMP CCrypto::
EncryptString(	BSTR bstrSrc, BSTR *pbstrResult	)
	{
	USES_CONVERSION;
	USES_CHECKHR_MSG( IID_ICrypto );
	HRESULT			hr				= S_OK;	
	HCRYPTKEY		hPrivateKey		= NULL;
	HCRYPTHASH		hDigSigHash		= NULL;
	LPBYTE			lpPrivateKey	= NULL;
	LPBYTE			lpFinalBuffer	= NULL;
	LPBYTE			lpSrcBytes		= NULL;
	LPBYTE			lpEncodedBytes	= NULL;

	ATLASSERT( pbstrResult	!= NULL	);
	try
		{
		CComBSTR	strSrc(bstrSrc);

		ClearDigitalSignature();
		if( !Initialize() )
			nStringID = IDS_ERROR_INITIALIZATION_FAILED,
			THROW_HRESULT( E_FAIL );

			//	Nothing to encrypt?
		ATLASSERT( strSrc.Length() > 0 );
		if( strSrc.Length() > 0 )
			{
			DWORD	dwEncryptSize	= 0; 
			DWORD	dwEncodedBytes	= 0;
			DWORD	dwPrivateKeySize= 0;
			DWORD	dwFinalBuffer	= 0;
			DWORD	dwVersion		= INMEMORY_FORMAT_VERSION;
			DWORD	dwEncryptedLen	= strSrc.Length();
		
			hPrivateKey = GeneratePrivateKey( &lpPrivateKey, 
											  &dwPrivateKeySize, 
											  INMEMORY_ENCRYPT_ALGORITHM );
			if(  hPrivateKey  &&
				lpPrivateKey	)
				{
				CBase64Helper	Base64Helper;
				
					//	Create the hash for digital signature 
				if( !CryptCreateHash( m_hContext, 
									  HASHING_ALGORITHM, 0, 0, 
									  &hDigSigHash ) )
					nStringID = IDS_ERROR_HASHCREATE_FAILED,
					THROW_HRESULT( E_FAIL );

					
					//	Copy the src string into a byte array
				lpSrcBytes = (LPBYTE)malloc( sizeof(BYTE) * strSrc.Length() + 1 );
				VERIFY_MALLOC( lpSrcBytes );
				strcpy( (char*)lpSrcBytes, W2A(strSrc) );
				
					//	Calculate the size of the encrypted buffer
				dwEncryptSize = strlen( (char*)lpSrcBytes );

					// Encrypt the src string and initialize the digital signature hash
				if( !CryptEncrypt(	hPrivateKey, 
									hDigSigHash, 
									TRUE, 
									0, 
									lpSrcBytes, 
									&dwEncryptSize, 
									dwEncryptSize		) )
					nStringID = IDS_ERROR_ENCRYPT_ENCRYPTION_FAILED,
					THROW_HRESULT( E_FAIL );		
			
					//	Calculate the total size of the resulting string (in bytes)
				dwFinalBuffer = SIZE_VERSION		 + 
								SIZE_PRIVATEKEY_SIZE +
								dwPrivateKeySize	 +
								SIZE_ENCRYPTED_DATA  + 
								dwEncryptSize;

					//	Create the final buffer
				lpFinalBuffer = (LPBYTE)malloc( ( sizeof(BYTE) * dwFinalBuffer ) + 1 );
				VERIFY_MALLOC( lpFinalBuffer );
					
					//	Build the encrypted blob in-memory
				memcpy( lpFinalBuffer, &dwVersion, sizeof(dwVersion) );
				memcpy( &lpFinalBuffer[ SIZE_VERSION ], &dwPrivateKeySize, sizeof(dwPrivateKeySize) );
				memcpy( &lpFinalBuffer[ SIZE_VERSION + SIZE_PRIVATEKEY_SIZE ], lpPrivateKey, dwPrivateKeySize );
				memcpy( &lpFinalBuffer[ SIZE_VERSION + SIZE_PRIVATEKEY_SIZE + dwPrivateKeySize ], &dwEncryptedLen, sizeof(dwEncryptedLen) );
				memcpy( &lpFinalBuffer[ SIZE_VERSION + SIZE_PRIVATEKEY_SIZE + dwPrivateKeySize + SIZE_ENCRYPTED_DATA ], lpSrcBytes, dwEncryptSize );

					//	Prepare the encrypted blob for the caller
				dwEncodedBytes = Base64Helper.Base64Encoder( lpFinalBuffer, dwFinalBuffer, (void**)&lpEncodedBytes );
				
					//	Convert encoded/encrypted bytes to zero-terminated string
				lpSrcBytes = (LPBYTE)realloc( lpSrcBytes, dwEncodedBytes + 1 );
				memcpy( lpSrcBytes, (PBYTE)GlobalLock( lpEncodedBytes ), dwEncodedBytes );
				lpSrcBytes[ dwEncodedBytes ] = '\0';
					
					//	Grab the digital signature
				if( !DigitallySignHash( hDigSigHash ) )
					nStringID = IDS_ERROR_DIGITALSIGNATURE_ENCRYPT_STRING,
					THROW_HRESULT( E_FAIL );

					//	Copy out to the caller
				*pbstrResult = ::SysAllocString( A2W((char*)lpSrcBytes) );				
				}
			}
		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}

		//	Cleanup
	if( hPrivateKey	)
		CryptDestroyKey( hPrivateKey );

	SAFE_MALLOC_FREE( lpSrcBytes	);
	SAFE_MALLOC_FREE( lpFinalBuffer );
	SAFE_MALLOC_FREE( lpPrivateKey	);

	if( hDigSigHash )
		CryptDestroyHash( hDigSigHash );	

	if( lpEncodedBytes )
		GlobalFree( lpEncodedBytes );

	return hr;
	}


STDMETHODIMP CCrypto::
DecryptString( BSTR bstrSrc, BSTR *pbstrResult )
	{
	USES_CONVERSION;
	USES_CHECKHR_MSG( IID_ICrypto );
	HRESULT		hr				= S_OK;	
	HCRYPTHASH	hDigSigHash		= NULL;
	HCRYPTKEY	hPrivateKey		= NULL;
	LPBYTE		lpSrcBytes		= NULL;
	HGLOBAL		hDecodedBytes	= NULL;
	PBYTE		lpDecodedBytes	= NULL;
	LPBYTE		lpEncryptedData = NULL;
	LPBYTE		lpPrivateKey	= NULL;	

	ATLASSERT( pbstrResult	!= NULL	);
	try
		{
		CBase64Helper	Base64;
		CComBSTR		bstrDecoded(bstrSrc);

        ClearDigitalSignature();
		if( !Initialize() )
			nStringID = IDS_ERROR_INITIALIZATION_FAILED,
			THROW_HRESULT( E_FAIL );
		
			//	Must be long enough
		ATLASSERT( ::SysStringLen( bstrSrc ) > ( SIZE_VERSION + SIZE_PRIVATEKEY_SIZE ) );
		if( ::SysStringLen( bstrSrc ) > ( SIZE_VERSION + SIZE_PRIVATEKEY_SIZE ) )
			{
			DWORD	dwVersion			= INVALID_FORMAT_VERSION;
			DWORD	dwPrivateKeySize	= 0;
			DWORD	dwEncryptedData		= 0;
			DWORD	dwDecodedBytes		= 0;

				//	Create the hash for digital signature 
			if( !CryptCreateHash( m_hContext, 
								  HASHING_ALGORITHM, 0, 0, 
								  &hDigSigHash ) )
				nStringID = IDS_ERROR_HASHCREATE_FAILED,
				THROW_HRESULT( E_FAIL );
			
				//	Covert the src encoded, encrypted string into a byte array
			lpSrcBytes = (LPBYTE)malloc( sizeof(BYTE) * bstrDecoded.Length() + 1 );
			VERIFY_MALLOC( lpSrcBytes );
			strcpy( (char*)lpSrcBytes, W2A(bstrDecoded) );

				//	Decode the bytes
			dwDecodedBytes = Base64.Base64Decoder(	lpSrcBytes, 
													strlen( (char*)lpSrcBytes ), 
													&hDecodedBytes );
			lpDecodedBytes = (PBYTE)GlobalLock( hDecodedBytes );

				//	Grab the version and private key size
			dwVersion		= (*((DWORD*)lpDecodedBytes));
			dwPrivateKeySize= (*((DWORD*)&lpDecodedBytes[ SIZE_VERSION ]));

				//	Validate the in-memory string format
			if( dwVersion != INMEMORY_FORMAT_VERSION ||
				dwDecodedBytes <= ( SIZE_VERSION + SIZE_PRIVATEKEY_SIZE + dwPrivateKeySize ) )
				nStringID = IDS_ERROR_UNSUPORTED_INMEMORY_ENCRYPTION_VERSION,
				THROW_HRESULT( E_FAIL );

				//	Grab the private key
			lpPrivateKey	= (LPBYTE)malloc( sizeof(BYTE) * dwPrivateKeySize );
			VERIFY_MALLOC( lpPrivateKey );
			memcpy( lpPrivateKey, &lpDecodedBytes[ SIZE_VERSION + SIZE_PRIVATEKEY_SIZE ], sizeof(BYTE) * dwPrivateKeySize );

			//	Import the private key into the CSP
			if( !CryptImportKey( m_hContext, 
								 lpPrivateKey, 
								 dwPrivateKeySize, 0, 0, 
								 &hPrivateKey		) )
				nStringID = IDS_ERROR_IMPORTPRIVATEKEY_FAILED,
				THROW_HRESULT( E_FAIL );


				//	Grab the encrypted data size
			dwEncryptedData = (*((DWORD*)&lpDecodedBytes[ SIZE_VERSION + SIZE_PRIVATEKEY_SIZE + dwPrivateKeySize ]));
				
				//	Grab the encrypted data
			lpEncryptedData = (LPBYTE)malloc( dwEncryptedData + 1 );
			VERIFY_MALLOC( lpEncryptedData );
			memcpy( lpEncryptedData, &lpDecodedBytes[	SIZE_VERSION + SIZE_PRIVATEKEY_SIZE + SIZE_ENCRYPTED_DATA + dwPrivateKeySize ], dwEncryptedData	);
				
				//	Perform the decryption
			if( !CryptDecrypt(	hPrivateKey, 
								hDigSigHash, 
								TRUE, 0, 
								lpEncryptedData, 
								&dwEncryptedData ) )
				nStringID = IDS_ERROR_DECRYPTSTRING_FAILED,
				THROW_HRESULT( E_FAIL );
			
				//	Copy the result to the caller
			lpEncryptedData[ dwEncryptedData ] = '\0';
			*pbstrResult = ::SysAllocString( A2W((char*)lpEncryptedData) );
			
				//	Digital signature
			if( !DigitallySignHash( hDigSigHash ) )
				nStringID = IDS_ERROR_DIGITALSIGNATURE_DECRYPT_STRING,
				THROW_HRESULT( E_FAIL );
			}

			//	Bad format
		else
			nStringID = IDS_ERROR_UNSUPORTED_INMEMORY_ENCRYPTION_VERSION,
			THROW_HRESULT( E_FAIL );

		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}

	SAFE_MALLOC_FREE( lpSrcBytes		);
	SAFE_MALLOC_FREE( lpPrivateKey		);
	SAFE_MALLOC_FREE( lpEncryptedData	);

	if( hPrivateKey	)
		CryptDestroyKey( hPrivateKey );

	if( hDecodedBytes )
		GlobalFree( hDecodedBytes );

	if( hDigSigHash	)
		CryptDestroyHash( hDigSigHash );
	
	return hr;
	}


STDMETHODIMP CCrypto::
Base64EncodeString(	BSTR bstrSrc, BSTR *pbstrResult	)
	{
	CBase64Helper	Base64;
	CComBSTR		bstrEncoded = Base64.Base64EncodeString( bstrSrc );
	return bstrEncoded.CopyTo( pbstrResult );
	}


STDMETHODIMP CCrypto::
Base64DecodeString( BSTR bstrSrc, BSTR *pbstrResult	)
	{
	CBase64Helper	Base64;
	CComBSTR		bstrDecoded = Base64.Base64DecodeString( bstrSrc );
	return bstrDecoded.CopyTo( pbstrResult );
	}


STDMETHODIMP CCrypto::
Base64EncodeFile( BSTR bstrSrc, VARIANT varDestination )
	{
	return Base64FileHelper( bstrSrc, varDestination );
	}


STDMETHODIMP CCrypto::
Base64DecodeFile( BSTR bstrSrc, VARIANT varDestination )
	{
	return Base64FileHelper( bstrSrc, varDestination, FALSE );
	}


STDMETHODIMP CCrypto::
Base64EncodeFileToString( BSTR  bstrSrc, 
						  BSTR* pbstrResult )
	{
	USES_CONVERSION;
	USES_CHECKHR_MSG( IID_ICrypto );
	FILE*		pSrcFile				= NULL;
	HRESULT		hr						= S_OK;
	LPBYTE		lpData[ FILE_READBYTES ]= {0}; 
    LPBYTE      lpResultBlob            = NULL;
	HGLOBAL		hEncodedBytes			= NULL;
	LPBYTE		pEncodedBytes			= NULL;
    DWORD       dwTotalRead             = 0;   
	CComBSTR	bstrResult;
	
	ATLASSERT( pbstrResult != NULL );
	try
		{
		pSrcFile = fopen( W2A(bstrSrc), "rb" );
		ATLASSERT( pSrcFile			!= NULL );
		
			//	Make sure the files opened
		if( pSrcFile == NULL )
			nStringID = IDS_ERROR_ENCODEDFILE_FILEOPENFAILED,
			THROW_HRESULT( E_FAIL );

            //  Read the file into memory - We need to anyway since the client wants a string back
		do
			{
            LPBYTE  lpTemp = NULL;

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

                //  Append the bytes to what has already been read
            dwTotalRead += dwCount;
            lpTemp = (LPBYTE)realloc( lpResultBlob, dwTotalRead + 1 );
            VERIFY_MALLOC( lpTemp );
            lpResultBlob = lpTemp;
            memcpy( &lpResultBlob[ dwTotalRead - dwCount ], lpData, dwCount );
			}
		while( !feof(pSrcFile) );
		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}

        //  Clean up
	if( pSrcFile )
		fclose( pSrcFile );

	if( SUCCEEDED( hr ) )
        {
        CBase64Helper	Base64;
        
            //  Encode the bits
        DWORD dwEncoded = Base64.Base64Encoder( (LPBYTE)lpResultBlob, dwTotalRead, &hEncodedBytes );				
		pEncodedBytes = (LPBYTE)GlobalLock( hEncodedBytes );

            //  Convert encoded bits to a BSTR
        bstrResult.Append( (LPCSTR)pEncodedBytes );
        hr = bstrResult.CopyTo( pbstrResult );
        GlobalFree( hEncodedBytes );
        }

    SAFE_MALLOC_FREE( lpResultBlob );
	return hr;
	}


STDMETHODIMP CCrypto::
Base64DecodeStringToFile( BSTR  bstrSrc, 
						  BSTR  bstrDestination )
	{
	USES_CONVERSION;
	USES_CHECKHR_MSG( IID_ICrypto );
	HRESULT		hr				= S_OK;
	LPBYTE		lpSrcBytes		= NULL;
	HGLOBAL		hDecodedBytes	= NULL;
	FILE*		pDestination	= NULL;
	CComBSTR	cbstrSrc( bstrSrc );

	try
		{
		CBase64Helper	Base64;
		DWORD			dwDecoded		= 0;

			//	Copy the source string to byte array
		lpSrcBytes = (LPBYTE)malloc( sizeof(BYTE) * cbstrSrc.Length() + 1 );
		VERIFY_MALLOC( lpSrcBytes );
		strcpy( (char*)lpSrcBytes, W2A(cbstrSrc) );

		dwDecoded = Base64.Base64Decoder( lpSrcBytes, strlen( (LPCSTR)lpSrcBytes ), &hDecodedBytes );

		pDestination = fopen( W2A(bstrDestination), "w+b" );
		if( pDestination )
			{
			LPBYTE	lpDecodedBytes = (LPBYTE)GlobalLock( hDecodedBytes );
			
				//	Write the result to the destination file
			fwrite( lpDecodedBytes, sizeof(BYTE), dwDecoded, pDestination );
			fflush( pDestination );

			if( ferror( pDestination ) )
				nStringID = IDS_ERROR_DECODED_FILEIO,
				THROW_HRESULT( E_FAIL );
			}
		}
	catch( HRESULT _hr )
		{
		CATCH_FAILED_HR( _hr );
		}

		//	Cleanup
	SAFE_MALLOC_FREE( lpSrcBytes );
	if( hDecodedBytes )
		GlobalFree( hDecodedBytes    );

	if( pDestination )
		fclose( pDestination );
	
	return hr;

⌨️ 快捷键说明

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