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

📄 crypto.cpp

📁 DSM Plugin.加密文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  Copyright (C) 2005 Sean E. Covel All Rights Reserved.
//
//  Created by Sean E. Covel
//
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//
// If the source code for the program is not available from the place from
// which you received this file, check 
// http://home.comcast.net/~msrc4plugin
// or
// mail: msrc4plugin@comcast.net
//
//
//
/////////////////////////////////////////////////////////////////////////////

//#include "stdafx.h"
#define _WIN32_WINNT 0x0410     //must be defined for the crypto api
#define _WIN32_WINDOWS 0x0410
#define WINVER 0x0400

#include <stdio.h>
#include <windows.h>
//#include <time.h>
//#include <tchar.h>


#include <wincrypt.h>       //windows crypto api
#include "crypto.h"
#include "logging.h"
#include "utils.h"

int CSP_PROV =	PROV_RSA_FULL;	//Microsoft Basic/Enhanced provider
char DEFAULTKEY[KEYSize];

CHAR szUserName[100];         // Buffer to hold the name of the key container.
DWORD dwUserNameLen = 100;    // Length of the buffer.


char CSP_NAME[CSP_SIZE];

DWORD VERIFY_CONTEXT_FLAG = CRYPT_VERIFYCONTEXT;
DWORD MACHINE_CONTEXT_FLAG = CRYPT_MACHINE_KEYSET;	//Test for Win98 winvnc problem
DWORD NULL_CONTEXT_FLAG = 0;
DWORD CONTEXT_FLAG = CRYPT_VERIFYCONTEXT;

DWORD KEYLEN = KEYLEN_128BIT;
DWORD MAXKEYLEN = KEYLEN_128BIT;	//I'm going to do something with this some day...


BOOL GenKey(char * sDefaultGenKey, DWORD keyLen)
{
	
    //Generates the RC4 key and writes it to a file
    //The key contains information about the algorithm used and
    //the key length.
    char GkeyFile[KEYFILENAME_SIZE];
	
    const int IN_BUFFER_SIZE    = 2048;
    const int OUT_BUFFER_SIZE   = IN_BUFFER_SIZE + 64; // extra padding
	
    HANDLE     hGKeyFile = 0;
    BYTE       pbBuffer[OUT_BUFFER_SIZE];
    HCRYPTPROV    hGProvider = 0;
    HCRYPTKEY     hGKey = 0;
    HCRYPTKEY     hGExchangeKey = 0;
    DWORD         dwByteCount;
    DWORD         dwBytesWritten;
    long rc;

	long iWinVer=0;
	long iCryptVer=0;

	KEYLEN = keyLen;

	InitVars(CSP_NAME, &iWinVer, &iCryptVer, &MAXKEYLEN);

    PrintLog((DEST,"GenKey. %d bit", (DWORD)(HIWORD(KEYLEN))));
	PrintLog((DEST,"OS is '%s'",WindowsName[iWinVer]));
	PrintLog((DEST,"Using provider |%s|",CSP_NAME));
	PrintLog((DEST,"Max Key Length %d",(DWORD)(HIWORD(MAXKEYLEN))));

#ifdef _WITH_REGISTRY

    REGISTRY *m_pREGISTRY;
    m_pREGISTRY = new REGISTRY(HKEY_CURRENT_USER, MSRC4_KEY_FILE, false);
    m_pREGISTRY->ReadItem(GkeyFile, KEYFILENAME_SIZE, INDEXVAL_KEYGEN, NULL);
    delete m_pREGISTRY;
#else
    strcpy(GkeyFile,sDefaultGenKey);
#endif
    

	//Windows OS before 2000 won't import ExponentOfOne key in a verify context.
	if (iWinVer >= WIN2000)
	{
		PrintLog((DEST,"Using NULL_CONTEXT"));
		CONTEXT_FLAG = NULL_CONTEXT_FLAG;
		szUserName[0] = '\0';
	}
	else
	{
		//PrintLog((DEST,"Using VERIFY_CONTEXT"));
		//CONTEXT_FLAG = VERIFY_CONTEXT_FLAG;
		PrintLog((DEST,"Using MACHINE_KEYSET"));
		CONTEXT_FLAG = MACHINE_CONTEXT_FLAG;
		//CONTEXT_FLAG = VERIFY_CONTEXT_FLAG;
		strcpy(szUserName, CTX);
		CreateContainer(szUserName);
	}

    rc = 0;

	rc = PrepContext(iWinVer, &hGProvider);

	PrintLog((DEST,"Generating key file: %s",GkeyFile));

    //open both the output file
	hGKeyFile = CreateFile(GkeyFile, GENERIC_WRITE, FILE_SHARE_READ, 
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	//check if the file created ok
	if (hGKeyFile == INVALID_HANDLE_VALUE)
	{
        PrintLog((DEST,"Failed to create key file. "));
		return false;
	}

	PrintLog((DEST,"Importing ExponentOfOne KeyBlob"));
    //HCRYPTKEY ExponentOfOneKey = NULL;
    if( !CryptImportKey(hGProvider, PrivateKeyWithExponentOfOne, sizeof(PrivateKeyWithExponentOfOne), 0, 0, &hGExchangeKey))
	{
        PrintLog((DEST,"Import ExponentOfOne Key failed.(GenKey)"));
		return false;
	}
	
	PrintLog((DEST,"Generating random key blob"));
    // Generate a random key blob
	if (! CryptGenKey(hGProvider, CALG_RC4, CRYPT_EXPORTABLE + KEYLEN, &hGKey))
	{
        PrintLog((DEST,"CryptGenKey failed. " ));
		return false;
	}
	
    // The first call to ExportKey with NULL gets the key size.
	dwByteCount=0;
	if (! CryptExportKey(hGKey, hGExchangeKey, SIMPLEBLOB, 0,  NULL, &dwByteCount))
	{
        PrintLog((DEST,"CryptExportKey failed. " ));
		return false;
	}
	
	if (dwByteCount == 0)
	{
        PrintLog((DEST,"CryptKeyLen == 0."));
		return false;
	}
	
	PrintLog((DEST,"Export the key blob"));
	//Generate the actual key
	rc = CryptExportKey(hGKey, hGExchangeKey, SIMPLEBLOB, 0, pbBuffer, 
		&dwByteCount);
    if (rc == 0)
	{
        PrintLog((DEST,"CryptExportKey2 failed. "));
		return false;
	}
	
	//assertion
	if (dwByteCount != BLOBSIZE)
	{
        PrintLog((DEST,"CryptKeyLen != BLOBSIZE."));
		return false;
	}
	
	// Write the "bitness" of the key.
	if (KEYLEN == 0x00800000)
	{
		DebugLog((DEST,"128 bit key."));
		WriteFile(hGKeyFile, "128 bit", 7, &dwBytesWritten, NULL);
	}
	else {
			if (KEYLEN == 0x00380000)
			{
				DebugLog((DEST,"56 bit key."));
				WriteFile(hGKeyFile, " 56 bit", 7, &dwBytesWritten, NULL);
			}
			else
			{
				DebugLog((DEST,"40 bit key."));
				WriteFile(hGKeyFile, " 40 bit", 7, &dwBytesWritten, NULL);
			}
	}

	// Write size of key blob
	WriteFile(hGKeyFile, &dwByteCount, sizeof(dwByteCount), &dwBytesWritten, NULL);
	
	//Write key blob itself
	WriteFile(hGKeyFile, pbBuffer, dwByteCount, &dwBytesWritten, NULL);
	
	// Clean up: release handles
	CryptDestroyKey(hGKey);
	CryptDestroyKey(hGExchangeKey);
	
	//We抮e finished using the CSP handle, so we must release it. We close the input and output files, and we抮e finished.
	CryptReleaseContext(hGProvider, 0);
	
    CloseHandle(hGKeyFile);

	return true;
}


long GetCryptoVersion() {
//Determine the Crypto API version

BYTE pbData[1000];
unsigned long cbData;
HCRYPTPROV    hProvider = 0;
BYTE *ptr = NULL;
DWORD version;
long rc = 0;

PrintLog((DEST,"GetCryptoVersion."));
PrintLog((DEST,"Acquiring the Crypto Context."));

// Get handle for the default provider (use RSA encryption).
PrintLog((DEST,"CryptAcquireContext |%d| |%s| |%s| |%d| |%d|",hProvider, NULL, NULL, PROV_RSA_FULL, CONTEXT_FLAG));
CryptAcquireContext(&hProvider, NULL, NULL, PROV_RSA_FULL , CONTEXT_FLAG );

if (hProvider == 0){
		PrintLog((DEST,"Crypto could not acquire a Crypto Provider Context. "));
		return 0;
}
else {

	PrintLog((DEST,"Crypto acquired a Crypto Provider Context. "));

	cbData = 1000;

	rc = CryptGetProvParam(
				hProvider,          // handle to an open cryptographic provider
				PP_VERSION,			//get VERSION information
				(BYTE *)&pbData,  // information on the version
				&cbData,            // number of bytes 
				0);       // flag for enumeration functions
	if (rc != TRUE)
	{
		PrintLog((DEST,"CryptGetProvParam failed to return the PP_VERSION.  %d",rc));
		return 0;
	}
}

if(!CryptReleaseContext(hProvider, 0)) {
    PrintLog((DEST,"Error during CryptReleaseContext."));
    return 0;
}

ptr = pbData;

version = *(DWORD *)ptr;

//version - M = major version, mm = minor version...
//  0x00000101 = Version 1.1

					//       Mmm        Mmm
if (version < 511)	//0x00000100-0x000001FF (0-511)
	return 1;

					//       Mmm        Mmm
if (version < 767)  //0x00000200-0x000002FF  (512-767)
	return 2;

return 0;

}


BOOL InitVars(char *szCSPName, long *iWinVer, long *iCryptVer, DWORD * iMaxKey) {

//Get the windows version, crypto version, best crypto provider, and best bit-depth supported.

HCRYPTPROV    hProvider = 0;                // crypto provider

	*iWinVer = 0;
	*iCryptVer = 0;
	*iMaxKey = 0;

	*iWinVer = WhatWindowsVer();
	
	PrintLog((DEST,"InitVars"));

	//*iCryptVer 
	*iCryptVer = GetCryptoVersion();

	if (*iCryptVer == 1) {
		//Version 1 doesn't support anything usefull for finding bit depth and whatnot...
		//I think you only see this on 95 anyway...
		//*** Only on 95 without the High Encryption pack ***
		//not much works with version 1.
		szCSPName[0] = '\0';	//default
		*iMaxKey = KEYLEN_40BIT;
	}
	else
	{
		//Version 2 has better features, but we don't want to waste a lot of time...

		if (*iWinVer>= WINXP) {	//XP and up come with 128bit out of the box.
			szCSPName[0] = '\0';	//default
			*iMaxKey = KEYLEN_128BIT;
		}
		else {	
			
			if (*iWinVer == WINNT) {  //NT does not support GetDefaultProvider function...
				//look for MS_ENHANCED_PROV
PrintLog((DEST,"CryptAcquireContext |%d| |%s| |%s| |%d| |%d|",hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
				CryptAcquireContext(&hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  				if (hProvider != 0){
					strcpy(szCSPName,MS_ENHANCED_PROV);
					*iMaxKey = KEYLEN_128BIT;
				}
				else {
					szCSPName[0] = '\0';
					*iMaxKey = KEYLEN_40BIT;
				}
			   CryptReleaseContext(hProvider, 0);
			}
			else {	//98, 98SE, ME, 2000
				//We gotta look and see what we have available...
				//I was going to use GetDefaultProvider, but it returns MS Base Provider
				//Even when the Enhanced provider is available...
PrintLog((DEST,"CryptAcquireContext |%d| |%s| |%s| |%d| |%d|",hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
				CryptAcquireContext(&hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  				if (hProvider != 0){
					strcpy(szCSPName, MS_ENHANCED_PROV);
					*iMaxKey = KEYLEN_128BIT;
				}
				else {
					szCSPName[0] = '\0';
					*iMaxKey = KEYLEN_40BIT;
				}
			   CryptReleaseContext(hProvider, 0);
			}
		}
	}


	//copy the values to the global variables
	strcpy(CSP_NAME, szCSPName);
	MAXKEYLEN = *iMaxKey;

	return true;
}


int ResetCrypto(HCRYPTKEY hKey)
{
  DWORD dwByteCount = 1;
  CHAR temp[] = "a";		//decrypt/encrypt some junk.

	//reset the crypto context to prepare for the next connection
	//true means "this is the last bunch of data, so reset"
    return CryptDecrypt(hKey, 0, true, 0, (BYTE *)temp, &dwByteCount);

}


int PrepContext(int iWinVer, HCRYPTKEY * hProvider)
{
		PrintLog((DEST,"PrepContext"));

	//Windows OS before 2000 won't import ExponentOfOne key in a verify context.
	if (iWinVer >= WIN2000)
	{
		PrintLog((DEST,"Using VERIFY_CONTEXT"));
		CONTEXT_FLAG = VERIFY_CONTEXT_FLAG;
		szUserName[0] = '\0';
	}
	else
	{
		//PrintLog((DEST,"Using NULL_CONTEXT"));
		//CONTEXT_FLAG = NULL_CONTEXT_FLAG;
		PrintLog((DEST,"Using MACHINE_KEYSET"));
		CONTEXT_FLAG = MACHINE_CONTEXT_FLAG;
		//CONTEXT_FLAG = NULL_CONTEXT_FLAG;

⌨️ 快捷键说明

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