Click here to Skip to main content
15,899,754 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.7K   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

 
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 
Ever wanted to use encryption, but got stuck trying to get the encrption key to the recipient? A real chicken and egg problem. The solution is that you can use Diffie-Hellman-Merkle key exchange.

Diffie-Hellman-Merkle key exchange uses y = g^x (mod p) to create a once-off shared secret encryption key of arbitrary length. This secret key can then be used to exchange data encrypted using the key. What makes DH key exchange fascinating is that is is not necessary to exchange secret information in order to 'share' the encryption key. Anyone evesdropping on the line cannot derive the key from the information exchanged during the negotiation process.

Security is based on the fact that it is mathematically infeasible to discover the key IF THE VALUES ARE LARGE ENOUGH. Adequate security typically utilizes keys in of 1000 bits. Security is enhanced due to the fact that a new, unique encryption key is generated each time.

The primary limitation is in performing large-integer arithmetic. Fortunately there are public/free implementations available. Or you can read Knuth and write one yourself. Check out the BigDigits library at www.di-mgt.com.au. Be aware that using this code it is possible to create arbitrarily long keys, which may have legal implications in your area. The key buffer is hard-limited to 51 4-byte integers (51*4=204bytes=1632bits), and will crash if you use a larger key buffer, so be warned.

The Way It Works

DH key exchange uses the following pattern (Bob (recipient) and Alice (sender) exchange messages, with Eve evesdropping).

First, the key format. This consists of three components g, x, and p.
g is the GENERATOR. Use a small prime, say 2, 3, 5, 7 etc.
x is the EXPONENT. This is the key, a random number of, say, 1024 bits.
p is the MODULUS. This is a large prime, typically of the same order as x (1024 bits).
Use CryptoApi, .NET crypto or any other service provider to create secure values and primes of this magnitude. Do not use Rnd!

1. Bob chooses a private key. (g, x1, and p) (generates these values)
   The magnitude of x1 is equivalent to the resulting encryption key size.
   x1 must be kept secret.
2. Bob calculates a new x2 value using x2 = g ^ x1 (mod p)
   Publishes this key (in a directory, web page, or email).
   g, x2, p

 [ EVE INTERCEPTS ]

3. Alice wants to send Bob secure data. She requires an encryption key. 
   She can establish a secret key with Bob, over a public medium, this way:
   Alice chooses a new random x3 value of the same order of magnitude as x2.
   She uses Bob's g and p values, leaving her with g, x3, p.
   x3 must be kept secret.
4. Alice calculates a public key x4 = g ^ x3 (mod p).
   She sends this to Bob over a public medium (g, x4, p). Bob aleady knows the values of g and p, since they are of his choosing. This can be a validation step - the values must match.

 [ EVE INTERCEPTS ]

5. Alice generates the encryption key x5 = x2 ^ x3 (mod p)
   Bob generates the encryption key x5 = x4 ^ x1 (mod p).


Alice and bob are now in possession of the same secret key. Eve intercepts all exchanges, but cannot (unless she is NSA!) derive the key value.

How does it work? To use an analogy from Simon Singh's The Code Book:
Say that keys are paint, in 3-pint tins. Alice and Bob agree on a public key - one pint of yellow paint. They each pick a secret color. Bob mixes one pint of yellow with 1 pint of his secret color, and sends this to Alice.
Alice mixes one pint of yellow with her secret color, and sends this to Bob.
Then Alice adds a pint of her secret color to Bob's tin, and Bob adds a pint of his secret color to Alice's tin.
Both tins are now the same color.
Eve can intercept the tins as they pass to and fro, she can even know that the public key is a pint of yellow. But she cannot determine the secret color because mixing paint is a one-way function.


Test Case (ALL NUMBERS IN HEX)

Follow this test case to see it working - note that in the real world, keys of 1000 bits or more would be used.
The symbol => refers to the result of calculating g ^ x (mod p). g, p are carried over.

   g=3 x1=9A2E p=10001 (Bob's private key, reused)<br />
 => g=3 x2=C366 p=10001 (Bob's public key, published, reused)<br />
 <br />
   g=3 x3=4C20 p=10001 (Alice's once-off random key, using Bob's g, p)<br />
 => g=3 x4=6246 p=10001 (Alice publishes this to Bob)<br />
<br />
   g=C366 x1=4C20 p=10001 (Alice calculates x2 ^ x3 (mod p))<br />
 => x5=DED4<br />
<br />
   g=6246 x4=9A2E p=10001 (Bob calculates x4 ^ x1 (mod p))<br />
 => x5=DED4 


Alice and Bob have both arrived at the same value: DED4. This is the key! Alice encrypts the data using this secret key, and sends the encrypted data to Bob, along with the public value x4, which Bob uses to calculate the key. Eve cannot take advantage of this information due to the one-way function g^x(mod p).

Web Services Secure Exchange Example

The following schematic shows how DHM key exchange could be used in a distributed environment, say between Web Services.

Note: x is the private key on each side. This is not exchanged. p is the public key which is exchanged.
ALICE (CLIENT)                    BOB  (SERVER)
---------------------             ---------------------
b = acquire_dh_key(bob)       ->  get_dh_public( return p; )
x = make_dh_private(b)
p = make_dh_public(b,x)
c = make_dh_crypt(b,x)
encrypt_data(c)
send_data_and_key(bob,p,data) ->  c = make_dh_crypt(p,x)
                                  decrypt_data(c)

In this way, one request is made to determine the server's public key, another is made to transfer the encrypted data along with the public info required for the server to calculate the encryption key. If the server's public key is known/cached, then the data can be sent using a single method-call each time. It is up to Alice to select a random message key (x) each time data is sent.

Since encryption keys are not reused, security is enhanced.

Implementations

Be aware that you will likely write flaws into your encryption code if you implement it all yourself. If possible, use a service from an established CSP (Crypto Service Provider). The CryptoAPI on Win32 supports creating and calculating DH keys, so take a look around and see what use you can make of existing code, even if it's just the secure random number generators. .NET supports various key exchange mechanisms, but they rely on asymetric algorithms such as RSA to keep the actual key safe whilst in transit.

DH key exchange never transmits the actual encryption key. This is what makes it useful, and well suited to a distributed environment. Use a proper encryption algorithm like Rijndael (AES), but derive and transmit the key using DH mechanisms.

One possible implementation is to use a simple XML framework to transmit the data/key package, possibly similar to the following:

<br />
<?xml version="1.0" ?><br />
<encryptedpackage><br />
  <key>NK89FNOF8LNKASDFW0934LNF09VNOECR3M089DFCMFHE7823JRS==</key><br />
  <data>FGKMSDFVCFN879EC89SDFASDFUHNOGS7834RMIUSHDF78T3BOLKJ34289=</data><br />
</encryptedpackage><br />


Key and Data values are base64 encoded for embedding in an XML document.

Happy coding.



Caractacus
www.caradoc.co.za
Ah, yes, I thought so.
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 
GeneralRe: What of small subgroup attacks? Pin
Griffter UK25-Apr-04 22:06
Griffter UK25-Apr-04 22:06 
GeneralRe: What of small subgroup attacks? Pin
mtlili26-Apr-04 9:02
mtlili26-Apr-04 9:02 
GeneralRe: What of small subgroup attacks? Pin
Griffter UK26-Apr-04 22:00
Griffter UK26-Apr-04 22:00 
GeneralRe: What of small subgroup attacks? Pin
Adam Nelson26-Apr-04 15:01
Adam Nelson26-Apr-04 15:01 
GeneralRe: What of small subgroup attacks? Pin
Jeffrey Walton18-Jul-08 10:00
Jeffrey Walton18-Jul-08 10:00 
GeneralRe: What of small subgroup attacks? Pin
Adam Nelson18-Jul-08 10:06
Adam Nelson18-Jul-08 10:06 
GeneralRe: What of small subgroup attacks? Pin
Marcus Carey16-Jan-07 5:20
Marcus Carey16-Jan-07 5:20 

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.