Could you send me the link to your custom Diffie-Hellman implemntation ?

+1 vote
asked Jun 16, 2015 by _Werner_ (130 points)

I'm working on Windows CE 6.0, CF 3.5 on a ARM1136JF-STM i.MX35 machine.
Thanks a lot.

related to an answer for: Failed to connect to SFTP
Applies to: Rebex Secure Mail

2 Answers

0 votes
answered Jun 16, 2015 by Tomas Knopp (58,560 points)
edited Jun 16, 2015 by Tomas Knopp

From our release notes I can see that this has been released as part of release 2012R1 so 2012R1 an all upcoming releases have automatic workaround:

Cryptography: Diffie-Hellman and DSA algorithms fall back to managed ModPow calculation on .NET CF with missing "Enhanced DSA and
Diffie-Hellman" CSPs.

So customers with support contract can download the 2012R1 version after logging in at http://www.rebex.net/protected.

If you want to give it a try for free, just download the latest freel trial of the Rebex SFTP for .NET client library.

0 votes
answered Nov 28, 2016 by ProgramForFun (100 points)
Greetings,

Sorry if this is the wrong place, but the website will not let me post and keeps redirecting me questions that don't match what I want.

I downloaded and installed rebex security looking for diffie-hellman examples. However, I was unable to find any and including the website found none at all. Are there any diffie-hellman code examples for C# and VB.NET? This would be greatly appreciated.

Also, attempted to create a tag for "diffie-hellman", but I don't have the points sense I'm new.

Thank you.
commented Nov 28, 2016 by Lukas Matyska (36,240 points)
A typical Diffie-Hellman key exchange looks like this:

       using Rebex.Security.Cryptography;

       // machine A: generate (public) parameters, generate ephemeral keypair for 'Alice', and get her public key
       var alice = new DiffieHellmanCryptoServiceProvider();
       var parameters = alice.ExportParameters(false);
       byte[] publicKeyAlice = alice.GetPublicKey();

       // machine B: import (public) parameters, generate ephemeral keypair for 'Bob', and get his public key
       var bob = new DiffieHellmanCryptoServiceProvider();
       bob.ImportParameters(parameters);
       byte[] publicKeyBob = bob.GetPublicKey();

       // machine A: compute shared key from Alice's private key and Bob's public key
       byte[] sharedKeyA = alice.GetSharedSecretKey(publicKeyBob);

       // machine B: compute shared key from Bob's private key and Alices's public key
       byte[] sharedKeyB = bob.GetSharedSecretKey(publicKeyAlice);

       // result of both computations is the same shared key
       Console.WriteLine(BitConverter.ToString(sharedKeyA));
       Console.WriteLine(BitConverter.ToString(sharedKeyB));

For non-Windows platforms, we provide `DiffieHellmanManaged` class, however please note it is very slow compared to the `DiffieHellmanCryptoServiceProvider` class.
commented Nov 28, 2016 by ProgramForFun (100 points)
Thank you Lukas for the reply.

I'm a little new to new to DH, but in looking at the code I'm not seeing how the parameters get's sent to Bob; bob.ImportParameters. Also, in the code it looks like the parameters and  publicKeyAlice get's sent to Bob, but the "parameters" cannot be converted to a string so how would I send it?

Thanks again.
commented Nov 28, 2016 by Lukas Pokorny (82,430 points)
The “parameters” are an instance of DiffieHellmanParameters, which is a simple structure:

public struct DiffieHellmanParameters
{
        // The generator.
        public byte[] G;

        // The prime modulus.
        public byte[] P;

        // The private key.
        public byte[] X;

        // The public key.
        public byte[] Y;
    }

Both the parameters and keys are byte arrays. You can convert them to strings for transport if needed, and then back to byte arrays on the other side. Using Convert.ToBase64String/Convert.FromBase64String is the most simple choice, writing a hexadecimal string encoder/parser is another possibility.

Just like any instance of .NET’s AsymmetricAlgorithm object, DiffieHellmanCryptoServiceProvider generates a key pair and optionally the parameters unless imported.

Calling alice.ExportParameters(false) generates parameters and key pair and returns an instance of DiffieHellmanParameters with only G (generator), P (prime) and Y set (public key – the same value you get by calling alice.GetPublicKey()).
Calling bob.ImportParameters(parameters) imports P and G. It generates a new key pair (using the same generator and prime) unless both Y and X are present as well.

This is another variant of the sample code that is easier to follow – P and G are generated at the beginning and the rest of the code is the same for Alice and Bob:

// parameters
    byte[] P;
    byte[] G;
           
    // generate P (prime) and G (generator)
    // (alternatively, you could you pre-generated P and G)
    using (var tmp = new DiffieHellmanCryptoServiceProvider())
    {
        var parameters = tmp.ExportParameters(false);
        P = parameters.P;
        G = parameters.G;
    }

    // machine A: import parameters, generate ephemeral keypair for 'Alice', and get her public key
    var inputParamsAlice= new DiffieHellmanParameters();
    inputParamsAlice.P = P;
    inputParamsAlice.G = G;
    var alice = new DiffieHellmanCryptoServiceProvider();
    alice.ImportParameters(inputParamsAlice);
    byte[] publicKeyAlice = alice.GetPublicKey();

    // machine B: import parameters, generate ephemeral keypair for 'Alice', and get her public key
    var inputParamsBob = new DiffieHellmanParameters();
    inputParamsBob.P = P;
    inputParamsBob.G = G;
    var bob = new DiffieHellmanCryptoServiceProvider();
    bob.ImportParameters(inputParamsBob);
    byte[] publicKeyBob = bob.GetPublicKey();

    // machine A: compute shared key from Alice's private key and Bob's public key
    byte[] sharedKeyA = alice.GetSharedSecretKey(publicKeyBob);

    // machine B: compute shared key from Bob's private key and Alices's public key
    byte[] sharedKeyB = bob.GetSharedSecretKey(publicKeyAlice);

    // result of both computations is the same shared key
    Console.WriteLine(BitConverter.ToString(sharedKeyA));
    Console.WriteLine(BitConverter.ToString(sharedKeyB));
...