Thread: crypto questions

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    69

    crypto questions

    I'm working on a program to export a public/private key pair that has been encrypted using a hashed password. i've been checking the error codes, and they all seem to check out okay, but i'm thinking the file output is incorrect (all i got was a single square in notepad, and a dot and a similey face in the cmd editor). maybe it has something to do with my pointers? i'm kinda stuck on this right now, so any help is appreciated. (unless it's working correctly as is )

    warning: long function ahead!

    Code:
    #include <iostream>
    #include <windows.h>
    #include <wincrypt.h>
    #include <fstream>
    #include <conio.h>
    #include <string>
    #include <cassert>
    using namespace std;
    
    void crypto();
    
    int main()
    {
    
    	crypto();
    	return 0;
    }
    
    void crypto()
    {
    
    	HCRYPTPROV	CSPhandle;
    	HCRYPTPROV	CSPhandlePass;
    	HCRYPTKEY	keyHandle;
    	HCRYPTKEY	keyExpHandle;
    	HCRYPTKEY	keyPassHandle;
    	HCRYPTHASH	hashPassHandle;
    //	CHAR		szContainerName;
    	LPCSTR		ContainerName = "keyContainer";
    	CHAR		ssPassword[512] = "password";
    	DWORD		dwLength=strlen(ssPassword);
    	DWORD*		blobSize;
    
    	BYTE*		expData;
    
    	ofstream outfile;
    	string filename = "keys.dat";
    
    	int returnCode = 0;
    	DWORD errorCode = 0;
    
    
    
    
    	//creating a container for the public/private key pair:
    
    	if (returnCode = CryptAcquireContext(
    		&CSPhandle,
    		ContainerName,
    		NULL,
    		PROV_RSA_FULL,
    		0))
    	{
    		errorCode = GetLastError();
    
    		cout<<"An existing key container has been opened. " <<returnCode <<" " <<errorCode <<endl;
    	}
    
    	else
    	{
    		returnCode = CryptAcquireContext(
    			&CSPhandle,
    			ContainerName,
    			NULL,
    			PROV_RSA_FULL,
    			CRYPT_NEWKEYSET);
    
    		errorCode = GetLastError();
    		
    		cout<<"A new key container has been created. " <<returnCode <<" " <<errorCode <<endl;
    	}
    
    	//generating the public/private key pair:
    	returnCode = CryptGenKey(
    		CSPhandle,
    		AT_SIGNATURE,
    		(1024U<<16) | CRYPT_EXPORTABLE,
    		&keyHandle);
    
    	errorCode = GetLastError();
    	
    	cout<<"Created a signature key pair. " <<returnCode <<" " <<errorCode <<endl;
    
    	//creating a container for the password key:
    	if (returnCode = CryptAcquireContext(
    		&CSPhandlePass,
    		NULL,
    		NULL,
    		PROV_RSA_FULL,
    		CRYPT_NEWKEYSET))
    	{
    
    		errorCode = GetLastError();
    	
    		cout<<"A new key container has been created for the password hash. " <<returnCode <<" " <<errorCode <<endl;
    	}
    
    	else
    	{
    		returnCode = CryptAcquireContext(
    			&CSPhandlePass,
    			NULL,
    			NULL,
    			PROV_RSA_FULL,
    			0);
    		
    		errorCode = GetLastError();
    
    		cout<<"An existing container has been opened for the password hash. " <<returnCode <<" " <<errorCode <<endl;
    	}
    
    	//creating hash object for hashing the password:
    
    	returnCode = CryptCreateHash(
    		CSPhandlePass,
    		CALG_MD5,
    		0,
    		0,
    		&hashPassHandle);
    
    	errorCode = GetLastError();
    
    	cout<<"An empty hash object has been created. " <<returnCode <<" " <<errorCode <<endl;
    
    	//hashing the password string:
    
    	returnCode = CryptHashData(
    		hashPassHandle,
    		(BYTE *)ssPassword,
    		dwLength,
    		0);
    
    	errorCode = GetLastError();
    
    	cout<<"Password hashed. " <<returnCode <<" " <<errorCode <<endl;
    
    
    	//creating a key based on the password:
    
    	returnCode = CryptDeriveKey(
    		CSPhandlePass,
    		CALG_RC2,
    		hashPassHandle,
    		0,
    		&keyPassHandle);
    
    	errorCode = GetLastError();
    
    	cout<<"Password key created. " <<returnCode <<" " <<errorCode <<endl;
    
    
    	//setting the export key to the key derived from password:
    
    	keyExpHandle = keyPassHandle;
    
    
    	//exporting the encrypted public/private key pair:
    
    		//getting the size of the data:
    	blobSize = new DWORD;
    	*blobSize = 0;
    
    	returnCode = CryptExportKey(
    		keyHandle,
    		0,
    		PRIVATEKEYBLOB,
    		0,
    		NULL,
    		blobSize);
    
    	errorCode = GetLastError();
    
    	cout<<"Return code / error code for sizing CEK call: " <<returnCode <<" " <<errorCode <<endl;
    /*	cout<<"Error codes:\n";
    	cout<<ERROR_INVALID_HANDLE <<endl;
    	cout<<ERROR_INVALID_PARAMETER <<endl;
    	cout<<ERROR_MORE_DATA <<endl;
    	cout<<(unsigned int)NTE_BAD_FLAGS <<endl;
    	cout<<(unsigned int)NTE_BAD_KEY <<endl;
    	cout<<(unsigned int)NTE_BAD_KEY_STATE <<endl;
    	cout<<(unsigned int)NTE_BAD_PUBLIC_KEY <<endl;
    	cout<<(unsigned int)NTE_BAD_TYPE <<endl;
    	cout<<(unsigned int)NTE_BAD_UID <<endl;
    	cout<<(unsigned int)NTE_NO_KEY <<endl;
    */
    	expData = new BYTE[*blobSize];
    
    		//exporting the data:
    	returnCode = CryptExportKey(
    		keyHandle,
    		0,
    		PRIVATEKEYBLOB,
    		NULL,
    		expData,
    		blobSize);
    
    	errorCode = GetLastError();
    
    	cout<<"Keys exported to expData. " <<returnCode <<" " <<errorCode <<endl;
    
    
    	//writing encrypted keys to file:
    
    	outfile.open(filename.c_str());
    	assert(outfile);
    	outfile<<expData;
    	cout<<expData <<endl;
    	outfile.close();
    
    
    	//cleaning up handles, etc.
    	delete blobSize;
    	delete expData;
    
    	CryptDestroyKey(keyHandle);
    	CryptDestroyKey(keyExpHandle);
    	CryptDestroyKey(keyPassHandle);
    
    	CryptDestroyHash(hashPassHandle);
    
    	CryptReleaseContext(CSPhandle, 0);
    	CryptReleaseContext(CSPhandlePass, 0);
    }

  2. #2
    Registered User
    Join Date
    Oct 2002
    Posts
    69
    well, i fixed the file output problem, just writing the file with binary instead of using the useless insertion operator.

    one more question: when i try to use the key that i generated from the hashed password, i get an invalid key error in the CryptExportKey calls.
    Code:
    	//setting the export key to the key derived from password:
    
    	keyExpHandle = keyPassHandle;
    
    
    	//exporting the encrypted public/private key pair:
    
    		//getting the size of the data:
    	blobSize = new DWORD;
    	*blobSize = 0;
    
    	returnCode = CryptExportKey(
    		keyHandle,
    		0,
    		PRIVATEKEYBLOB,
    		0,
    		NULL,
    		blobSize);
    
    	errorCode = GetLastError();
    
    	cout<<"Return code / error code for sizing CEK call: " <<returnCode <<" " <<errorCode <<endl;
    
    	expData = new BYTE[*blobSize];
    
    		//exporting the data:
    	returnCode = CryptExportKey(
    		keyHandle,
    		0,
    		PRIVATEKEYBLOB,
    		NULL,
    		expData,
    		blobSize);
    the code works fine when i substitute 0 for the hExpKey (the 2nd parameter to CryptExportKey), but the output is not going to be encrypted. i tried both keyExpHandle and keyPassHandle in case it was something wrong with the assignment of the key, but met with the same result.

    any ideas?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. questions....so many questions about random numbers....
    By face_master in forum C++ Programming
    Replies: 2
    Last Post: 07-30-2009, 08:47 AM
  2. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  3. Several Questions, main one is about protected memory
    By Tron 9000 in forum C Programming
    Replies: 3
    Last Post: 06-02-2005, 07:42 AM
  4. Trivial questions - what to do?
    By Aerie in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 12-26-2004, 09:44 AM
  5. questions questions questions.....
    By mfc2themax in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 08-14-2001, 07:22 AM