NAME¶
FBB::DiffieHellman - Diffie-Hellman PKI, computing shared keys
SYNOPSIS¶
#include <bobcat/diffiehellman>
Linking option:
-lbobcat
DESCRIPTION¶
The class
FBB::DiffieHellman computes shared keys (shared secrets) using
the Diffie-Hellman (1976) algorithm. The Diffie-Hellman algorithm uses public
and private information. The public information consists of a
prime
(e.g., a prime number consisting of 1024 bits), a
generator (for which
the value 5 is commonly used), and the value
generator mod prime, where
private is a randomly selected large number, which is the private
information.
The Diffie-Hellman algorithm is commonly used to compute a shared key which can
be used to encrypt information sent between two parties. One party, which in
this man-page is called the
initiator computes the prime and defines
the generator. The prime is computed by
FBB::DiffieHellman’s
first constructor, while the generator is passed to this constructor as one of
its arguments. For the generator the value 5 is often used.
Next the initiator passes its public information, consisting of the prime, the
generator, and the value
generator mod prime to the other party, which
in this man-page is called the
peer. The public information is written
in binairy, big-endian form to file using the member
save. The
initiator may optionally save the private information to a separate file as
well.
The peer thereupon receives the initiator’s public information. The
initialor’s public information is read by a
FBB::DiffieHellman
constructor either expecting the name of a file or a
std::istream
containining the initiator’s public information.
Having obtained the prime and generator, the peer’s public (and,
optionally, private information) is saved by also calling
save. This
results, among other things, in the value
generator mod prime, but now
using the peer’s private information.
At this point the peer is already able to compute the shared key. The key is
returned by calling the
key member, which returns the shared key as a
series of bytes stored in a
std::string.
Before the initiator can compute the shared key the peer’s
generator
mod prime value must be available. The peer sends the saved public data to
the initiator. The initiator then passes the peer’s public data either
by file name or by
std::istream to the
key member, returning the
shared key.
Perfect Forward Secrecy and Ephemeral Diffie Hellman
If the initiator and peer decide not to save their private information
Perfect Forward Secrecy and
Ephemeral Diffie Hellman may be
obtained. Here, the procedure is applied as follows:
- o
- Initiator and peer have agreed upon and securely exchanged a long-lasting
common secret, which may be used in combination with, e.g., symmetric
encryption methods.
- o
- Applying the abovementioned procedure, the private information is never
saved on file. Consequently, the shared key, once computed, cannot be
reconstructed anymore.
- o
- The value generator mod prime is not sent to either peer or
initiator `in the clear’, but encrypted using the long-lasting
common secret. As the current implementation saves all public information
on file, it’s probably easiest to encrypt the file containing the
public information.
- o
- The recipients, having recieved the other party’s encrypted public
information, decrypt it using the long-lasting shared secret and compute
the the shared key.
- o
- As the secret information is not kept, the shared key cannot be
reconstructed, while a Man-In-The-Middle attack is prevented by only
exchanging encrypted public information.
- o
- The shared key can now be used to encrypt a communication session
NAMESPACE¶
FBB
All constructors, members, operators and manipulators, mentioned in this
man-page, are defined in the namespace
FBB.
INHERITS FROM¶
-
PUBLIC ENUMERATION¶
The enumeration
FBB::DiffieHellman::SecretKey has two values:
- o
- DONT_SAVE_SECRET_KEY, indicating that the secret information should
not be saved on file;
- o
- SAVE_SECRET_KEY, indicating that the secret information should be
saved on file;
CONSTRUCTORS¶
- o
- DiffieHellman(size_t primeLength = 1024, size_t generator = 5,
bool progress = false):
This constructor computes a prime of the specified length, and initializes
the public information with the indicated generator. If progress is
true, the progress of the prime construction process is shown to
std::cout by a series of dots, minuses and plusses. Generating a
suitable prime may fail, resulting in an FBB::Exception being
thrown. Unless the generator is specified as 2 or 5 the warning
cannot check the validity of generator ... is inserted into
the mstream(3bobcat)’s wmsg object. A warning is also
inserted if the provided generator is not a generator for the computed
prime.
- This constructor should be called by the initiator to start the
Diffie-Hellman shared key computation procedure.
- o
- DiffieHellman(std::string const &initiatorPublicFileName):
This constructor should be called by the peer, after having received the
initiator’s public info. It makes the initiator’s public
information available to the peer, after which the peer’s public
and private information can be computed.
- o
- DiffieHellman(std::stream &initiatorPublicStream):
This constructor acts like the previous constructor, expecting a
std::istream rather than a file name. It should be called by the
peer, after having received the initiator’s public info. It makes
the initiator’s public information available to the peer, after
which the peer’s public and private information can be
computed.
- o
- DiffieHellman(std::string const &initiatorPublicFileName,
std::string const &initiatorPrivateFileName):
Unless the initiator’s DiffieHellman object is still
available, this constructor should again be called by the initiator, to
load the initiator’s public and private data.
- o
- DiffieHellman(std::stream &initiatorPublicStream, std::stream
&initiatorPrivateStream):
This constructor acts like the previous constructor, expecting
std::istreams rather than file names. It should be called by the
initiator, to load the initiator’s public and private info. Copy
and move constructors are available.
OVERLOADED OPERATORS¶
Copy and move assignment operators are available.
MEMBER FUNCTIONS¶
- o
- std::string key() const:
This member should be called by the peer. It returns the shared key. If the
key cannot be computed, or if the key is not resistant to the small group
attack (i.e., if the key equals 1, or is at least equal to the public
prime value, or if key mod prime != 1), then an
FBB::Exception is thrown.
- o
- std::string key(std::string const &peerPublicFileName) const:
This member should be called by the initiator. It skips the data referring
to the prime and generator found in peerPublicFileName and then
reads the peer’s generator mod prime value. If this value
cannot be read or if the key is not resistant to the small group attack
(cf. the description of the previous key member) then an
FBB::Exception is thrown. It returns the shared key.
- o
- std::string key(std::istream const &peerPublicStream) const:
This member should be called by the initiator. It acts like the previous
key member, reading the peer’s generator mod prime
value from peerPublicStream. It returns the shared key.
- o
- void save(std::string const &basename, SecretKey action =
DONT_SAVE_SECRET_KEY):
This member should be called by the initiator. It saves the public
information on the file ’basename’.pub. The
information is written in binary, big-endian format, using the following
organization:
- - the size of the prime in bytes;
- the prime’s bytes;
- the size of the generator in bytes;
- the generator’s bytes;
- the size of the public info ( generator mod prime) in bytes;
- the public info’s bytes.
- If action is specified as SAVE_SECRET_KEY then the private
information is written in binary, big-endian format, using the following
organization:
- - the size of the private information in bytes;
- the private information bytes.
EXAMPLE¶
When called without arguments, the example program generates Diffie-Hellman
parameters writing the initiator’s public and private information to,
respectively,
init.pub and
init.sec.
When called with one argument,
init.pub is read, and the peer’s
public and private information is written to, respectively,
peer.pub
and
peer.sec. Next, the (peer’s) shared key is written to
peerkey.
When called with two arguments,
init.pub and
init.sec are read, as
well as the peer’s public information (on the file
peer.pub).
Next, the (initiator’s) shared key is written to
initkey.
The files
peerkey and
initkey should be identical.
#include <fstream>
#include <iostream>
#include <bobcat/diffiehellman>
using namespace FBB;
using namespace std;
int main(int argc, char **argv)
try
{
if (argc == 1)
{
DiffieHellman dh(1024, 5, true);
dh.save("init", DiffieHellman::SAVE_SECRET_KEY);
}
if (argc == 2)
{
DiffieHellman dh("init.pub");
dh.save("peer", DiffieHellman::SAVE_SECRET_KEY);
string key = dh.key();
cout << "Key length: " << key.length() << ’\n’;
ofstream outkey("peerkey");
outkey.write(key.data(), key.length());
}
if (argc == 3)
{
DiffieHellman dh("init.pub", "init.sec");
string key = dh.key("peer.pub");
cout << "Key length: " << key.length() << ’\n’;
ofstream outkey("initkey");
outkey.write(key.data(), key.length());
}
}
catch (std::exception const &exc)
{
std::cout << exc.what() << ’\n’;
}
FILES¶
bobcat/diffiehellman - defines the class interface
SEE ALSO¶
bobcat(7),
bigint(3bobcat)
BUGS¶
None Reported.
DISTRIBUTION FILES¶
- o
- bobcat_3.23.01-x.dsc: detached signature;
- o
- bobcat_3.23.01-x.tar.gz: source archive;
- o
- bobcat_3.23.01-x_i386.changes: change log;
- o
- libbobcat1_3.23.01-x_*.deb: debian package holding the
libraries;
- o
- libbobcat1-dev_3.23.01-x_*.deb: debian package holding the
libraries, headers and manual pages;
- o
- http://sourceforge.net/projects/bobcat: public archive location;
BOBCAT¶
Bobcat is an acronym of `Brokken’s Own Base Classes And
Templates’.
COPYRIGHT¶
This is free software, distributed under the terms of the GNU General Public
License (GPL).
AUTHOR¶
Frank B. Brokken (
f.b.brokken@rug.nl).