Click here to Skip to main content
Click here to Skip to main content

Tagged as

Shared Key Generation using Diffie-Hellman

, 25 Mar 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
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 (|).

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.

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.

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)

Share

About the Author

Jonathan C Dickinson
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

 
Questiondoubts regarding deffie hellman implementation in C# PinmemberMember 98566945-Mar-13 2:04 
AnswerRe: doubts regarding deffie hellman implementation in C# PinmemberJonathan C Dickinson5-Mar-13 2:42 
QuestionC# ECC encrypt/decrypt? PinmemberMember 151309928-Oct-09 4:40 
GeneralIncorrect IDisposable pattern and unnecessary finalizer PinmemberCrazyCanuck2-Apr-08 15:16 
GeneralRe: Incorrect IDisposable pattern and unnecessary finalizer PinmemberCrazyCanuck2-Apr-08 15:24 
GeneralRe: Incorrect IDisposable pattern and unnecessary finalizer PinmemberJonathan C Dickinson19-Aug-08 9:26 
GeneralIDisposable PinmemberJoel Lucsy26-Mar-08 11:27 
AnswerRe: IDisposable PinmemberJonathan C Dickinson26-Mar-08 22:20 
GeneralRe: IDisposable PinmemberJoel Lucsy27-Mar-08 10:07 
GeneralRe: IDisposable PinmemberJonathan C Dickinson19-Aug-08 9:25 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 25 Mar 2008
Article Copyright 2008 by Jonathan C Dickinson
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid