Click here to Skip to main content
15,888,802 members
Articles / Desktop Programming / MFC
Article

Diffie-Hellman Key Exchange Example

Rate me:
Please Sign up or sign in to vote.
3.81/5 (30 votes)
14 Nov 2008CPOL2 min read 290.2K   9.6K   53   59
An example of how an encryption key can be shared by two users using the Diffie-Hellman key exchange approach.

Introduction

It's often required that a message be encrypted between two parties for secure communication. There are plenty of algorithms out there for encryption that are very secure, but their weakness lies in transporting the encryption key. The Diffie-Hellman key exchange protocol allows people to exchange keys in a manner that does not allow an eavesdropper to calculate the key in a fast manner.

This code demonstrates the use of this type of key exchange.

How to Use the Demo Project

To demonstrate the use of the key exchange, run two copies of the demo application. Set one to be the sender and the other to be a receiver.

The sender should generate the public keys, and the sender's interim key. Paste these values into the appropriate text boxes in the receiver application. The receiver should then click to generate his interim key, and copy this key into the "receiver's interim key" textbox on the sender application. Both applications should then be able to generate the same key by clicking "Generate Key".

Using the Source Code

The DiffieHellman class is simple to use and should be integrated in the following manner:

Make an instance of the class - (i.e. CDiffieHellman *DH = new CDiffieHellman;)

The sender application then does the following:

C++
__int64 n = 0;
__int64 g = 0;
__int64 SInterim = 0;
__int64 RInterim = 0;
__int64 key = 0; 

DH->CreateKeys(g,n);
DH->CreateSenderInterKey(SInterim);

//The sender now sends (n, g, and SInterim) to the receiving application
//This can be done unencrypted because they are public keys
//Now we wait until the reciever send us their interim key lets say RInterim

DH->CreateSenderEncryptionKey(key,RInterim);
//The shared encryption key is now the value of 'key'

The receiving application does the following:

C++
__int64 n = 0;
__int64 g = 0;
__int64 SInterim = 0;
__int64 RInterim = 0;
__int64 key = 0;

//Wait for the values of (n,g, and SInterim) to be sent here

DH->CreateRecipientInterKey(RInterim);

//Now send the RInterim key to the sender application

DH->CreateRecipientEncryptionKey(key,SInterim);
//The shared encryption key is now the value of 'key'

Extra Functions

There are some private member functions of the CDiffieHellman class that you may find useful, and please feel free to use them.

  • The GeneratePrime() function generates a large prime number.
  • The MillerRabin and IsItPrime functions can be used in conjunction to test primality.
  • The XtoYmodN is a function to raise x to the power of y in modulus n. Even though it sounds impossible for a computer to work out, say 150 million to the power of 150 million, this can be done in modulus n by using the power chaining method.

Further Help

Should you require any additional help, please do not hesitate to contact me. I would be interested in hearing your comments, suggestions and any questions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: GUID problem FIXED Pin
qaziejaz8-Oct-07 22:36
qaziejaz8-Oct-07 22:36 
GeneralMagetting errors coz of GUID Pin
adeelg14-Oct-05 15:44
adeelg14-Oct-05 15:44 
GeneralDH 1024 bits Pin
Y G14-Sep-05 10:39
Y G14-Sep-05 10:39 
GeneralRe: DH 1024 bits Pin
Hashbullet30-Mar-07 1:07
Hashbullet30-Mar-07 1:07 
QuestionLimitations? Pin
gthakral10-Aug-05 9:54
gthakral10-Aug-05 9:54 
AnswerRe: Limitations? Pin
Griffter UK10-Aug-05 22:17
Griffter UK10-Aug-05 22:17 
Generalruntime optimization Pin
haneen28-Jul-05 5:55
haneen28-Jul-05 5:55 
GeneralRe: Generating Primes, DES and a whole lot more! Pin
Griffter UK29-Jul-05 4:12
Griffter UK29-Jul-05 4:12 
First off, the best way to use Diffie Hellman should be to use tried and tested API's
[Microsoft Cryptographic Libraries for Diffie-Hellman]

You can use the Microsoft Cryptographic Service Providers to achieve a lot of your cryptography needs. Lookup CryptAcquireContext and go from there - everything from RSA to DES to Diffie-Hellman and so on. I've included an example here of how to generate a prime using the Microsoft CryptoAPI. At first glance the prime doesn't always seem to look prime because it's last byte is an even number. However please note that the BYTE array contains octects!

To use the GeneratePrime function shown below, include <wincrypt.h> and then something like:


	BYTE *prime     = NULL;<br />
	DWORD primesize = 0;<br />
<br />
	GeneratePrime(&prime, &primesize);



Here is the GeneratePrime function (using RSA).

BOOL GeneratePrime(BYTE **prime, DWORD *cbPrime) <br />
{<br />
	HCRYPTPROV	 hCryptProv				= NULL;<br />
	HCRYPTHASH	 hHash					= NULL;<br />
	BOOL		 AcquiredContext		= FALSE;<br />
	BOOL		 AcquiredPrime			= FALSE;<br />
<br />
	//Attempt to acquire a cryptographic context<br />
	if(CryptAcquireContext(&hCryptProv,	NULL, NULL, PROV_RSA_FULL, 0)== FALSE)<br />
	{<br />
		//No context established for this machine, create new key set<br />
		if(GetLastError() == NTE_BAD_KEYSET)<br />
			AcquiredContext = CryptAcquireContext(&hCryptProv,	NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);<br />
	}<br />
	else<br />
		AcquiredContext = TRUE;<br />
	<br />
	//Context Acquired lets Generate a key<br />
	if (AcquiredContext==TRUE)<br />
	{<br />
		HCRYPTKEY hEncryptionKey = NULL;<br />
		<br />
		//Generate a 512-bit key<br />
		BOOL  bGenEncKey = CryptGenKey(hCryptProv, CALG_RSA_KEYX, (512 << 16) | CRYPT_EXPORTABLE, &hEncryptionKey);<br />
		if (bGenEncKey)<br />
		{			<br />
			//Get the size of the key blob<br />
			DWORD KeyLength = 0;<br />
			if (CryptExportKey(hEncryptionKey, NULL, PRIVATEKEYBLOB ,0, NULL, &KeyLength)==TRUE)<br />
			{<br />
				if (KeyLength>0)<br />
				{<br />
					//Allocate a key blob<br />
					BYTE *PrivateKeyBlob = (BYTE *) malloc((size_t)KeyLength);<br />
					if (PrivateKeyBlob)<br />
					{<br />
						//Export the blob<br />
						if (CryptExportKey(hEncryptionKey, NULL, PRIVATEKEYBLOB ,0, PrivateKeyBlob, &KeyLength)==TRUE)<br />
						{<br />
							PUBLICKEYSTRUC pks    = {0};<br />
							RSAPUBKEY      rsapub = {0};<br />
<br />
							//Get the Public Key and RSA information<br />
							memcpy(&pks,    PrivateKeyBlob, sizeof(PUBLICKEYSTRUC));<br />
							memcpy(&rsapub, PrivateKeyBlob + sizeof(PUBLICKEYSTRUC), sizeof(RSAPUBKEY));<br />
<br />
							//Calculate the size and offset of the prime numbers<br />
							DWORD KeySizeBytes = rsapub.bitlen / 16;<br />
							DWORD ModSizeBytes = rsapub.bitlen / 8;<br />
							DWORD OffsetPrimeP = sizeof(PUBLICKEYSTRUC) +  sizeof(RSAPUBKEY) + ModSizeBytes;<br />
							DWORD OffsetPrimeQ = sizeof(PUBLICKEYSTRUC) +  sizeof(RSAPUBKEY) + ModSizeBytes + KeySizeBytes;<br />
<br />
							//Allocate sufficient memory to hold the primes<br />
							*prime = (BYTE *) malloc((size_t) KeySizeBytes);<br />
												<br />
							if (*prime)<br />
							{<br />
								//Copy the prime from the key blob<br />
								*cbPrime = KeySizeBytes;<br />
                                memcpy(*prime, PrivateKeyBlob + OffsetPrimeP, KeySizeBytes);<br />
								AcquiredPrime = TRUE;								<br />
							}<br />
						}<br />
					}<br />
				}<br />
			}<br />
<br />
			CryptDestroyKey(hEncryptionKey);<br />
		}<br />
<br />
		CryptReleaseContext(hCryptProv, 0);<br />
	}<br />
<br />
	return AcquiredPrime;<br />
	<br />
}


Anyway hope this helps. If you look at the CryptoAPI by Microsoft you will see that encrypting with DES is simple! It also supports many other encryption algorithms along with hashing Algorithms, Public-Private Key and Signature algorithms - it's a very powerful library indeed.

If you need any more help, let me know.

Best Regards,

Lee
QuestionRe: Generating Primes, DES and a whole lot more! Pin
noooomen31-Oct-06 10:57
noooomen31-Oct-06 10:57 
Generalpublic key cryptography Pin
Anonymous16-Apr-05 9:21
Anonymous16-Apr-05 9:21 
GeneralRe: public key cryptography Pin
Griffter UK17-Apr-05 21:57
Griffter UK17-Apr-05 21:57 
Generalquestion Pin
Member 18357576-Apr-05 11:40
Member 18357576-Apr-05 11:40 
GeneralHelp required regarding IKE Pin
dendude21-Nov-04 19:58
dendude21-Nov-04 19:58 
GeneralCoding Language Pin
archanagoel11-May-04 22:30
archanagoel11-May-04 22:30 
QuestionWhat encryption library ? Pin
pb949413-Jan-04 21:02
pb949413-Jan-04 21:02 
AnswerRe: What encryption library ? Pin
Griffter UK13-Jan-04 22:12
Griffter UK13-Jan-04 22:12 
GeneralRe: What encryption library ? Pin
pb949414-Jan-04 1:56
pb949414-Jan-04 1:56 
GeneralRe: What encryption library ? Pin
Griffter UK14-Jan-04 2:33
Griffter UK14-Jan-04 2:33 
GeneralRe: What encryption library ? Pin
pb949414-Jan-04 3:28
pb949414-Jan-04 3:28 
GeneralRe: What encryption library ? Pin
Griffter UK14-Jan-04 3:44
Griffter UK14-Jan-04 3:44 
GeneralRe: What encryption library ? Pin
caractacus14-Jan-04 23:52
caractacus14-Jan-04 23:52 
QuestionWhat of small subgroup attacks? Pin
Adam Nelson9-Jan-04 6:03
Adam Nelson9-Jan-04 6:03 
AnswerRe: What of small subgroup attacks? Pin
Griffter UK10-Jan-04 23:29
Griffter UK10-Jan-04 23:29 
GeneralRe: What of small subgroup attacks? Pin
Adam Nelson11-Jan-04 4:55
Adam Nelson11-Jan-04 4:55 
GeneralRe: What of small subgroup attacks? Pin
mtlili25-Apr-04 9:16
mtlili25-Apr-04 9:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.