Skip to content

levisre/KeyExchange

Repository files navigation

Simple Key Exchange web service

Description

This is a small demo webservice in Ruby using Sinatra Framwork and OpenSSL to create a (not so) secure key exchange between client and server using three methods: RSA, Diffie Hellman Ephemeral (DHE) and Elliptic Curve Diffie Hellman Ephemeral (ECDHE).

  • With RSA, the scenario is:

    • Client chooses a random AES key and random Init Vector
    • Client encrypts key and iv using pre-defined RSA public key.
    • Client sends encrypted data to server.
    • Server receives encrypted data, then uses private key located on server to decrypt to get key
    • Now both client and server have key, and use it to encrypt data in each request/response after that.

Pros:

+ Speed is fast (maybe the fastest)
+ Very easy to implement

Cons:

+ Pure AES key is transferred during connection. They're just protected by RSA
  • With DHE, the scenario is:

    • Client creates DH instance, which contains base G, modulus p, its own private a and public A
    • Client sends G, p, A to server.
    • Server creates DH instance from G and p sent by client, calculates its own private b and public B, and calculates Shared secret s by using A sent by client.
    • Server sends B back to client
    • Client uses B to calculate Shared secret s
    • Both client and server use first 16 bytes of shared secret s as AES Key, and use it to encrypt data in each request/response after that.`

Pros:

+ AES Key is not transferred during connection, they're calculated on client and server.

Cons:

+ Slow speed (when DH Key Size is big, it needs to generate values from the very beginning of key exchange process whenever client make a call to this api, this maybe resolved using static DH params, see `gen_dhparam.rb` to know how to generate DH param in Ruby)
+ Can't use RSA as an overall layer (in this case, due to the large amount of data being sent)
+ Bit harder to implement

NOTE: To use static DH Parameters, both client and server have to agree to use the same fixed DH param, then modify the code.

File server.rb, API /dhe, change them to:

# file  dhparam.pem is pre-generated and pre-shared on both client and server
serverDH = OpenSSL::PKey::DH.new File.read("dhparam.pem")

File ``client.rb, method sendDHE`, change them to:

# file  dhparam.pem is pre-generated and pre-shared on both client and server
clientDH = OpenSSL::PKey::DH.new File.read("dhparam.pem")
# Must be used to generate public and private keypair before it can be used.
clientDH.generate_key!
# Since base G and modulus p is pre-shared, so they needn't to be sent during key exchange
# Just need to generate new A and a
dhStruct = {
	"A" => clientDH.pub_key.to_s(16)
}
  • With ECDHE, the scenario is:

    • Client creates ECDH instance, which generates a keypair cpub and cpriv using prime256v1 group
    • Client sends cpub to server
    • Server creates ECDH instance, which generates a keypair, spub and spriv using prime256v1 group
    • Server computes shared secret s by using client' cpub
    • Server sends spub to client
    • Client computes shared secret s by using server' spub
    • Both client and server use first 16 bytes of shared secret s as AES Key, and use it to encrypt data in each request/response after that.`

Pros:

+ Slightly fast and more secure
+ AES Key are not transferred during connection, they're calculated on client and server.
+ Can use RSA as an overall layer to make it more secure (in this case)

Cons:

+ Bit harder to implement

How to use

NOTE: Requires ruby >= 2.3.0, as requested by openssl gems

Install gems using

$ bundle install

Execute server:

$ ruby server.rb

By default, the server is at http://localhost:4567/

Test with client:

$ ruby client.rb

File Contents

  • server.rb: Main web service, exposing APIs for clients to call

  • client.rb: The name explains it all ;)

  • make_keypair.rb: Simple Ruby script to generate RSA Keypair using OpenSSL

  • private_key: RSA Private key in PEM format generated by make_keypair.rb

  • pubkey.pub: RSA Public key in PEM format generated by make_keypair.rb

  • Gemfile: Ruby gems list to use with bundle

  • README.md: What you're reading

  • gen_dhparam.rb: Generate DH params

  • network_sample.pcap: Sample network traffic captured

  • dhparam.pem: Static DH parameters generated by gen_dhparam.rb

About

Simple Implement of Key Exchange in Ruby

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages