Click here to Skip to main content
15,883,558 members
Articles / Programming Languages / C#

Shared Key Generation using Diffie-Hellman

Rate me:
Please Sign up or sign in to vote.
4.89/5 (11 votes)
25 Mar 2008CPOL2 min read 79K   6.5K   26   11
Generate an encryption key between two parties and foil the eavesdropper

Introduction

Sometimes you cannot rely on technologies such as TLS or SSL to protect your passwords on-the-wire: one example is programming against a device with limited capabilities. Furthermore, passwords may need to be stored locally on the machine (e.g. 'remember me' checkbox): this is hard or impossible using salt/salt+hash algorithms.

One solution would be to include the encryption key on both the client at compile time. This opens up a security hole because the source code can simply be decompiled to obtain the secret key.

Another solution would be to send the key over-the-wire when encryption is needed. However, a eavesdropper may be able to sniff out the encryption key.

This solution allows a key to be generated as encryption is required.

A simple explanation that I came across is that you should image a trunk with two padlocks on it. These padlocks have different keys that each party carries with them: the trunk may only be opened once both keys have been obtained.

Background

This article presents a C# implementation of the Diffie-Hellman algorithm. I recommend reading the Wikipedia article to get a grounding in the algorithm: but it is surprisingly easy. Note that the prime and base are transmitted, but if they are compromised it has no effect on the security of the transaction.

Using the Code

The demonstration program should give you everything you need.

The only class you should need to interact with is the DiffieHellman class.

This class contains three methods.

Generate Request

This generates a request packet. This packet contains the p (shared prime) and g (shared base) fields, as well as the originator's portion of the key. Each field is delimited using a pipe (|).

C#
protected virtual void OnClientConnected(string packet)
{
    currentClient.Dh = new DiffieHellman(256).GenerateRequest();
    networkSocket.Send(currentClient.Dh.ToString());
}

Generate Response

This generates a response packet. This packet contains only the receiver's portion of the key.

C#
protected virtual void OnDiffieHellmanReceived(string packet)
{
    this.Dh = new DiffieHellman(256).GenerateResponse(packet);
    this.Key = Dh.Key;
    networkSocket.Send(Dh.ToString());
    networkSocket.Send(Encrpyt(this.Password));
}

Receive Response

This allows the originator to finalize her/his key.

C#
protected virtual void OnPacketReceived(string packet)
{
    if(currentClient.MustDh)
    {
        currentClient.Dh.HandleResponse(packet);
        currentClient.Key = currentClient.Dh.Key;
        currentClient.MustDh = false;
    }
    else
    {
        currentClient.Password = currentClient.Decrypt(packet);
        this.Authenticate(currentClient);
        if(!currentClient.Authenticated)
            currentClient.ForceDisconnect("Invalid Credentials.");
    }
}

Points of Interest

Note that I deliberately chose to call the entities originator and receiver. The originator need not be a server and the receiver need not be a client.

Portions of this code are based on the code provided by Chew Keong TAN.

History

  • 25th March, 2008: Initial post
    Fixed a small error in the receive response section (MustDh was set to true instead of false)

License

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


Written By
Software Developer (Junior) SourceCode (K2)
South Africa South Africa
Jonathan Dickinson started programming at age eight when he got a VIC 20.

He used BASIC for the following four years, followed by Visual Basic for 3 years, and then got his hands on C# Beta 1 in March 2001. The transistion from BASIC to a C-Derivative was a challenging one. Since then he has dabbled with numerous programming languages including C/++, Java/script, Euphoria, Matlab, Octave, Actionscript, Python, Ruby and a limited amount of Assembler. He knows, like any developer worth his salt, a variety of markup languages such as XML and HTML.

He is currently working on several open source projects: and is most excited about a CIL Operating System called Ensemble.

Jonathan spends most of his time working but finds time for pet projects. His true loves are those who are close to him and programming: so he spends most of his time with his girlfriend and programming. He enjoys creating fusions between hardware and software, but he still has a lot more to learn about hardware.

Comments and Discussions

 
QuestionDiffie-Hellman Pin
Mohammad_Kabalan27-Dec-15 10:47
Mohammad_Kabalan27-Dec-15 10:47 
Questiondoubts regarding deffie hellman implementation in C# Pin
Member 98566945-Mar-13 1:04
Member 98566945-Mar-13 1:04 
AnswerRe: doubts regarding deffie hellman implementation in C# Pin
Jonathan C Dickinson5-Mar-13 1:42
Jonathan C Dickinson5-Mar-13 1:42 
QuestionC# ECC encrypt/decrypt? Pin
adam syria28-Oct-09 3:40
adam syria28-Oct-09 3:40 
GeneralIncorrect IDisposable pattern and unnecessary finalizer Pin
CrazyCanuck2-Apr-08 14:16
CrazyCanuck2-Apr-08 14:16 
GeneralRe: Incorrect IDisposable pattern and unnecessary finalizer Pin
CrazyCanuck2-Apr-08 14:24
CrazyCanuck2-Apr-08 14:24 
GeneralRe: Incorrect IDisposable pattern and unnecessary finalizer Pin
Jonathan C Dickinson19-Aug-08 8:26
Jonathan C Dickinson19-Aug-08 8:26 
GeneralIDisposable Pin
Joel Lucsy26-Mar-08 10:27
Joel Lucsy26-Mar-08 10:27 
AnswerRe: IDisposable Pin
Jonathan C Dickinson26-Mar-08 21:20
Jonathan C Dickinson26-Mar-08 21:20 
GeneralRe: IDisposable Pin
Joel Lucsy27-Mar-08 9:07
Joel Lucsy27-Mar-08 9:07 
GeneralRe: IDisposable Pin
Jonathan C Dickinson19-Aug-08 8:25
Jonathan C Dickinson19-Aug-08 8:25 

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.