Diffie-Hellman Key Exchange

From Crypto++ Wiki

Jump to: navigation, search

Contents

What you should know prior to use

You should understand the general Diffie-Hellman algorithm.

Mathematical Problem

The underlying mathematical problem of DH key Exchange is Discrete Logarithms.

Crypto++ classes and methods

DH(
   RandomNumberGenerator rng,
   int keySize
);

DH(
   Integer prime,
   Integer base
);

// dreijer: I know I got the variable types wrong above but all the templated stuff in Doxygen makes it really hard to figure out what types the constructors actually accept. Please fill in, Wei.

Examples

Generating a secret key

The following example illustrates how two hosts, Alice and Bob, agree on a shared secret key using Diffie-Hellman key exchange.

Alice generates a prime and base which she shares with Bob. (The prime and base can also simply be hardcoded into the application.) Alice then generates a pair of public and private integers. The public part is shared with Bob.

Bob uses the prime and base that he received from Alice to generate a pair of public and private integers. The public part is shared with Alice.

//////////////////////////////////////////////////////////////////////////
// Alice

// Initialize the Diffie-Hellman class with a random prime and base
AutoSeededRandomPool arngA;
RandomNumberGenerator& rngA = *dynamic_cast<RandomNumberGenerator *>(&arngA); 
DH dhA(rngA, 128);

// Extract the prime and base. These values could also have been hardcoded 
// in the application
Integer iPrime = dhA.GetGroupParameters().GetModulus();
Integer iGenerator = dhA.GetGroupParameters().GetSubgroupGenerator();

SecByteBlock privA(dhA.PrivateKeyLength());
SecByteBlock pubA(dhA.PublicKeyLength());
SecByteBlock secretKeyA(dhA.AgreedValueLength());

// Generate a pair of integers for Alice. The public integer is forwarded to Bob.
dhA.GenerateKeyPair(rngA, privA, pubA);

//////////////////////////////////////////////////////////////////////////
// Bob

AutoSeededRandomPool arngB;
RandomNumberGenerator& rngB = *dynamic_cast<RandomNumberGenerator *>(&arngB); 
// Initialize the Diffie-Hellman class with the prime and base that Alice generated.
DH dhB(iPrime, iGenerator);

SecByteBlock privB(dhB.PrivateKeyLength());
SecByteBlock pubB(dhB.PublicKeyLength());
SecByteBlock secretKeyB(dhB.AgreedValueLength());

// Generate a pair of integers for Bob. The public integer is forwarded to Alice.
dhB.GenerateKeyPair(rngB, privB, pubB);

//////////////////////////////////////////////////////////////////////////
// Agreement

// Alice calculates the secret key based on her private integer as well as the
// public integer she received from Bob.
if (!dhA.Agree(secretKeyA, privA, pubB))
	return false;

// Bob calculates the secret key based on his private integer as well as the
// public integer he received from Alice.
if (!dhB.Agree(secretKeyB, privB, pubA))
	return false;

// Just a validation check. Did Alice and Bob agree on the same secret key?
if (memcmp(secretKeyA.begin(), secretKeyB.begin(), dhA.AgreedValueLength()))
	return false;

return true;

Using Diffie-Hellman to generate an AES key

Building on the previous example. Note that the example uses in-place encryption and decryption where the input and output buffers are identical:

int aesKeyLength = SHA256::DIGESTSIZE; // 32 bytes = 256 bit key
int defBlockSize = AES::BLOCKSIZE;

// Calculate a SHA-256 hash over the Diffie-Hellman session key
SecByteBlock key(SHA256::DIGESTSIZE);
SHA256().CalculateDigest(key, secretKeyA, secretKeyA.size()); 

// Generate a random IV
byte iv[AES::BLOCKSIZE];
arngA.GenerateBlock(iv, AES::BLOCKSIZE);

char message[] = "Hello! How are you.";
int messageLen = (int)strlen(plainText) + 1;

//////////////////////////////////////////////////////////////////////////
// Encrypt

CFB_Mode<AES>::Encryption cfbEncryption(key, aesKeyLength, iv);
cfbEncryption.ProcessData((byte*)message, (byte*)message, messageLen);

//////////////////////////////////////////////////////////////////////////
// Decrypt

CFB_Mode<AES>::Decryption cfbDecryption(key, aesKeyLength, iv);
cfbDecryption.ProcessData((byte*)message, (byte*)message, messageLen);
Personal tools