One of the Greatest Advancements in Cybersecurity — The Diffie Hellman Method

The Diffie-Hellman (DH) method is perhaps one of the greatest inventions in Cybersecurity and was created by Whitfield Diffie and Marty…

One of the Greatest Advancements in Cybersecurity — The Diffie Hellman Method

The Diffie-Hellman (DH) method is perhaps one of the greatest inventions in Cybersecurity and was created by Whitfield Diffie and Marty Hellman:

With the DH method, Bob creates a random value (b) and Alice also creates a random value (a). Next, Bob computes:

B=g^b (mod p)

and sends it to Alice. Alice computes:

A=g^a (mod p)

and sends this to Bob. Bob raises the value of A to the power of b and takes (modp), and Alice raises B to the power of a and takes (mod p). In the end, they will have the same shared value:

g^{ab} (mod p)

This can then be used to derive an encryption key that they can use for a secure tunnel (Figure 1). Overall, p is the large prime number, and also known as the shared modulus between Bob and Alice.

Figure 1: The Diffie Hellman key exchange method

Code

First we create a folder named “bc_dh”, and then go into that folder.We can create a Dotnet console project for .NET 8.0 with:

dotnet new console --framework net8.0

Next, some code [here]:

namespace EH
{

using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Asn1.X9;

using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Digests;
using System.Text;
using System.Security.Cryptography;

class Program
{

static void Main(string[] args)
{

try {

var size=256;



if (args.Length >0) size=Convert.ToInt32(args[0]);




var aliceKey = GeneratorUtilities.GetKeyPairGenerator ("DH");
DHParametersGenerator aliceGenerator = new DHParametersGenerator ();
aliceGenerator.Init(size, 100, new SecureRandom ());
DHParameters aliceParameters = aliceGenerator.GenerateParameters ();

var aliceKGP = new DHKeyGenerationParameters (new SecureRandom (), aliceParameters);
aliceKey.Init (aliceKGP);

var aliceKeyPair = aliceKey.GenerateKeyPair ();
var aliceKeyAgree = AgreementUtilities.GetBasicAgreement ("DH");
aliceKeyAgree.Init (aliceKeyPair.Private);


var bobKey = GeneratorUtilities.GetKeyPairGenerator ("DH");
DHParametersGenerator bobGenerator = new DHParametersGenerator ();
bobGenerator.Init(size, 100, new SecureRandom ());


var bobKGP = new DHKeyGenerationParameters (new SecureRandom (), aliceParameters);
aliceKey.Init (bobKGP);

var bobKeyPair = aliceKey.GenerateKeyPair ();
var bobKeyAgree = AgreementUtilities.GetBasicAgreement ("DH");
bobKeyAgree.Init (bobKeyPair.Private);


var aliceAgree = aliceKeyAgree.CalculateAgreement (bobKeyPair.Public);
var bobAgree = bobKeyAgree.CalculateAgreement (aliceKeyPair.Public);



Console.WriteLine("Key size:\t{0}",size);
Console.WriteLine("g:\t\t{0}\nP:\t\t{1}",aliceParameters.G,aliceParameters.P);

var a= (DHPrivateKeyParameters) aliceKeyPair.Private;
Console.WriteLine("\nAlice Private Key:\t{0}", a.X);
var A= (DHPublicKeyParameters) aliceKeyPair.Public;
Console.WriteLine("Alice Public Key:\t{0}",A.Y);

var b= (DHPrivateKeyParameters) bobKeyPair.Private;
Console.WriteLine("Bob Private Key:\t{0}",b.X);
var B= (DHPublicKeyParameters) bobKeyPair.Public;
Console.WriteLine("Bob Public Key:\t\t{0}",B.Y);

Console.WriteLine("\nAlice Key:\t{0}",aliceAgree);
Console.WriteLine("Bob Key:\t{0}",bobAgree);
if (aliceAgree.Equals (bobAgree)) Console.WriteLine("Keys match");


} catch (Exception e) {
Console.WriteLine("Error: {0}",e.Message);
}

}
}
}



A sample run gives [here]:

Key Alice: 00921EDABAF33C4BBF29FD968E1480A5B52DC78EAFC5E3EE5A4F61359B12B5B11F
Key size: 256
g: 53965533115804605872298563439496250720754098454743318440150613624071335473374
P: 86209811022279296289999958940719805134068303737059616784337932983110932423767

Alice Private Key: 20639018536622076888943213070140010524686003766180688150243903655365293376910
Alice Public Key: 18647567625403045632663512627236807213714247777705465225176122695109356246406
Bob Private Key: 24871797456858289729500901773072557033917896874665754328579903642021407998271
Bob Public Key: 27971843771376139168845037856412439638595959690524265511293696548912187000059

Alice Key: 29596317805230711901195460750019977687409626885820282938455758371325708124436
Bob Key: 29596317805230711901195460750019977687409626885820282938455758371325708124436
Keys match

Now, let’s try these values with Python:

>>> g=32259974487183794416499361372713990702644486074496240708135562418518132654939
>>> p=69234343638616341294341802070224047203994183137085651021419312836532414307987
>>> a=16547342261270997888576284742384751809929302191652453904568191074081009056381
>>> A=pow(g,a,p)
>>> print (A)
68871015261301621898691329237236329560993238933340856839493134997803993018121

This agrees with Alice’s public key. Now for Bob:

>>> b=1924183266892706636821740708766318587774348404629964294853747941353163203900
>>> B=pow(g,b,p)
>>> print (B)
26889109636431132458440992472548015781681995210325136654900321789840740213139

and which agrees with Bob’s public key.Now let’s compute the shared secret:

>>> KeyA=pow(B,a,p)
>>> KeyB=pow(A,b,p)
>>> print (KeyA)
67276705861661430366025633569922408078630863545838188854396733719920518569346
>>> print (KeyB)
67276705861661430366025633569922408078630863545838188854396733719920518569346

Conclusions

Is the Diffie-Hellman method amazing? These days, we don’t use discrete logarithms, which need to be at least 1,024 bits in size. Unfortunately, for this size, it would take too long to perform the computations, so Elliptic Curve methods are used, such as with ECDH.

Here is a quick overview on key exchange methods: