.TH "FBB::DiffieHellman" "3bobcat" "2005\-2023" "libbobcat\-dev_6\&.04\&.00" "Diffie Hellman key computations" .PP .SH "NAME" FBB::DiffieHellman \- Diffie\-Hellman PKI, computing shared keys .PP .SH "SYNOPSIS" \fB#include \fP .br Linking option: \fI\-lbobcat \-lcrypto\fP .PP .SH "DESCRIPTION" .PP The class \fBFBB::DiffieHellman\fP computes shared keys (shared secrets) using the Diffie\-Hellman (1976) algorithm\&. The Diffie\-Hellman algorithm uses public and private information, providing a public key infrastructure (PKI)\&. The public information consists of a \fIprime\fP (e\&.g\&., a prime number consisting of 1024 bits), a \fIgenerator\fP (for which the value 5 is commonly used), and (using \fI**\fP to represent the power operator on integral values) the value \fIgenerator ** private mod prime\fP, where \fIprivate\fP is a randomly selected large number, which is the private information\&. .PP 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 \fIinitiator\fP, computes the prime and defines the generator\&. The prime is computed by \fBFBB::DiffieHellman\fP\(cq\&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\&. .PP Next the initiator passes its public information, consisting of the prime, the generator, and the value \fIpow(generator, private) mod prime\fP to the other party, which in this man\-page is called the \fIpeer\fP\&. The public information is written in binairy, big\-endian form to file using the member \fIsave\fP\&. The initiator may optionally save the private information to a separate file as well\&. .PP The peer thereupon receives the initiator\(cq\&s public information\&. The initialor\(cq\&s public information is read by a \fBFBB::DiffieHellman\fP constructor either expecting the name of a file or a \fIstd::istream\fP containining the initiator\(cq\&s public information\&. .PP Having obtained the prime and generator, the peer\(cq\&s public (and, optionally, private information) is saved by also calling \fIsave\fP\&. This results, among other things, in the value \fIpow(generator, private) mod prime\fP, but now using the peer\(cq\&s private information\&. .PP At this point the peer is already able to compute the shared key\&. The key is returned by calling the \fIkey\fP member, which returns the shared key as a series of bytes stored in a \fIstd::string\fP\&. .PP Before the initiator can compute the shared key the peer\(cq\&s \fIgenerator ** private mod prime\fP value must be available\&. The peer sends the saved public data to the initiator\&. The initiator then passes the peer\(cq\&s public data either by file name or by \fIstd::istream\fP to the \fIkey\fP member, returning the shared key\&. .PP \fBPerfect Forward Secrecy and Ephemeral Diffie Hellman\fP .PP If the initiator and peer decide not to save their private information \fIPerfect Forward Secrecy\fP and \fIEphemeral Diffie Hellman\fP may be obtained\&. Here, the procedure is applied as follows: .PP .IP 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\&. .IP o Applying the abovementioned procedure, the private information is never saved on file\&. Consequently, the shared key, once computed, cannot be reconstructed anymore\&. .IP o The value \fIgenerator ** private mod prime\fP is not sent to either peer or initiator `in the clear\(cq\&, but encrypted using the long\-lasting common secret\&. As the current implementation saves all public information on file, it\(cq\&s probably easiest to encrypt the file containing the public information\&. .IP o The recipients, having received the other party\(cq\&s encrypted public information, decrypt it using the long\-lasting shared secret and compute the the shared key\&. .IP 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\&. .IP o The shared key can now be used to encrypt a communication session .PP \fBDocument encryption using Diffie Hellman\fP .PP As with PKI in general, the Diffie Hellman key exchange method itself is not normally used for encrypting documents\&. Instead, it is usually used to exchange the key that is used for symmetric encryption methods like 3DES and CBC\&. These symmetric encryption methods are available through, e\&.g\&., Bobcats\(cq\& \fIEncryptBuf, DecryptBuf,\fP and \fIISymCryptStream\fP classes\&. .PP .SH "NAMESPACE" \fBFBB\fP .br All constructors, members, operators and manipulators, mentioned in this man\-page, are defined in the namespace \fBFBB\fP\&. .PP .SH "INHERITS FROM" \- .PP .SH "CONSTRUCTORS" .IP o \fBDiffieHellman(size_t primeLength = 1024, size_t generator = 5, bool progress = false)\fP: .br This constructor computes a prime of the specified length, and initializes the public information with the indicated generator\&. The prime length must at least be 1024 or an \fIFBB::Exception\fP is thrown\&. If \fIprogress\fP is \fItrue\fP, the progress of the prime construction process is shown to \fIstd::cout\fP by a series of dots, minuses and plusses\&. Generating a suitable prime may fail, resulting in an \fIFBB::Exception\fP being thrown\&. Unless the generator is specified as 2 or 5 the warning \fIcannot check the validity of generator \&.\&.\&.\fP is inserted into the \fBmstream\fP(3bobcat)\(cq\&s \fIwmsg\fP object\&. A warning is also inserted if the provided generator is not a generator for the computed prime\&. .IP This constructor should be called by the initiator to start the Diffie\-Hellman shared key computation procedure\&. .IP .IP o \fBDiffieHellman(FBB::BigInt const &prime, size_t generator = 5, bool progress = false)\fP: .br Alternatively, this constructor can be used by the initiator after separately having constructed the prime to use\&. The prime must at least be 1024 bits long\&. .IP .IP o \fBDiffieHellman(std::string const &initiatorPublicFileName)\fP: .br This constructor should be called by the peer, after having received the initiator\(cq\&s public info\&. It makes the initiator\(cq\&s public information available to the peer, after which the peer\(cq\&s public and private information can be computed\&. .IP .IP o \fBDiffieHellman(std::stream &initiatorPublicStream)\fP: .br This constructor acts like the previous constructor, expecting a \fIstd::istream\fP rather than a file name\&. It should be called by the peer, after having received the initiator\(cq\&s public info\&. It makes the initiator\(cq\&s public information available to the peer, after which the peer\(cq\&s public and private information can be computed\&. .IP .IP o \fBDiffieHellman(std::string const &initiatorPublicFileName, std::string const &initiatorPrivateFileName)\fP: .br Unless the initiator\(cq\&s \fIDiffieHellman\fP object is still available, this constructor should again be called by the initiator, to load the initiator\(cq\&s public and private data\&. .IP .IP o \fBDiffieHellman(std::stream &initiatorPublicStream, std::stream &initiatorPrivateStream)\fP: .br This constructor acts like the previous constructor, expecting \fIstd::istreams\fP rather than file names\&. It should be called by the initiator, to load the initiator\(cq\&s public and private info\&. .PP Copy and move constructors (and assignment operators) are available\&. .PP .SH "MEMBER FUNCTIONS" .IP o \fBstd::string key() const\fP: .br 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 \fIkey ** ((prime \- 1) / 2) mod prime != 1\fP), then an \fIFBB::Exception\fP is thrown\&. .IP .IP o \fBstd::string key(std::string const &peerPublicFileName) const\fP: .br This member should be called by the initiator\&. It skips the data referring to the prime and generator found in \fIpeerPublicFileName\fP and then reads the peer\(cq\&s \fIgenerator ** private mod prime\fP 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 \fIkey\fP member) then an \fIFBB::Exception\fP is thrown\&. It returns the shared key\&. .IP .IP o \fBstd::string key(std::istream const &peerPublicStream) const\fP: .br This member should be called by the initiator\&. It acts like the previous \fIkey\fP member, reading the peer\(cq\&s \fIgenerator ** private mod prime\fP value from \fIpeerPublicStream\fP\&. It returns the shared key\&. .IP .IP o \fBvoid save(std::string const &basename)\fP: .br This member should be called by the initiator\&. It saves the public information on the file \fI\(cq\&basename\(cq\&\&.pub\fP\&. The information is written in binary, big\-endian format, using the following organization: .IP \- the size of the prime in bytes; .br \- the prime\(cq\&s bytes; .br \- the size of the generator in bytes; .br \- the generator\(cq\&s bytes; .br \- the size of the public info (\fIgenerator ** private mod prime\fP) in bytes; .br \- the public info\(cq\&s bytes\&. .br .IP In addition the private information is written to the file \fI\(cq\&basename\(cq\&\&.sec\fP in binary, big\-endian format, using the following organization: .IP \- the size of the private information in bytes; .br \- the private information bytes\&. .PP .SH "EXAMPLE" .PP When called without arguments, the example program generates Diffie\-Hellman parameters writing the initiator\(cq\&s public and private information to, respectively, \fIinit\&.pub\fP and \fIinit\&.sec\fP\&. .PP When called with one argument, \fIinit\&.pub\fP is read, and the peer\(cq\&s public and private information is written to, respectively, \fIpeer\&.pub\fP and \fIpeer\&.sec\fP\&. Next, the (peer\(cq\&s) shared key is written to \fIpeerkey\fP\&. .PP When called with two arguments, \fIinit\&.pub\fP and \fIinit\&.sec\fP are read, as well as the peer\(cq\&s public information (on the file \fIpeer\&.pub\fP)\&. Next, the (initiator\(cq\&s) shared key is written to \fIinitkey\fP\&. .PP The files \fIpeerkey\fP and \fIinitkey\fP should be identical\&. .PP .nf #include #include #include #include \(dq\&\&.\&./diffiehellman\(dq\& using namespace FBB; using namespace std; int main(int argc, char **argv) try { if (argc == 1) { cout << \(dq\&1: create prime and generator, write to \(cq\¶ms\(cq\&\en\(dq\& \(dq\&2: create secret and public parts, arg 2: 0 or 1,\en\(dq\& \(dq\& write secret and public parts to \&.sec and \(dq\& \(dq\&\&.pub\en\(dq\& \(dq\&3: create common key arg 2: 0 or 1,\en\(dq\& \(dq\& 0: write common0 using 0\&.pub, 0\&.sec and 1\&.pub\en\(dq\& \(dq\& 1: write common1 using 1\&.pub, 1\&.sec and 0\&.pub\en\(dq\& ; return 0; } switch (*argv[1]) // using generator == 5 { case \(cq\&1\(cq\&: { ofstream out = Exception::factory(\(dq\¶ms\(dq\&); out << hex << DiffieHellman::prime(1024, true, true) << \(cq\&\en\(cq\&; } break; case \(cq\&2\(cq\&: { char *nr = argv[2]; if (nr == 0 || \(dq\&01\(dq\&s\&.find(*nr) == string::npos) throw Exception{} << \(dq\&mode \(cq\&2\(cq\& needs 0 or 1 as 2nd argument\(dq\&; ifstream in = Exception::factory(\(dq\¶ms\(dq\&); BigInt prime; in >> hex >> prime; DiffieHellman dh{ prime }; dh\&.save(nr); } break; case \(cq\&3\(cq\&: { char *nr = argv[2]; if (nr == 0 || \(dq\&01\(dq\&s\&.find(*nr) == string::npos) throw Exception{} << \(dq\&mode \(cq\&3\(cq\& needs 0 or 1 as 2nd argument\(dq\&; DiffieHellman dh{ nr + \(dq\&\&.pub\(dq\&s, nr + \(dq\&\&.sec\(dq\&s }; cout << \(dq\&common key computed by \(dq\& << nr << \(dq\&:\en\(dq\& << hex << dh\&.key((nr[0] == \(cq\&0\(cq\& ? \(cq\&1\(cq\& : \(cq\&0\(cq\&) + \(dq\&\&.pub\(dq\&s) << \(cq\&\en\(cq\&; } break; default: throw Exception{} << \(dq\&undefined action `\(dq\& << *argv[1] <<\(cq\&\e\(cq\&\(cq\&; } } catch (std::exception const &exc) { std::cout << exc\&.what() << \(cq\&\en\(cq\&; } .fi .PP .SH "FILES" \fIbobcat/diffiehellman\fP \- defines the class interface .PP .SH "SEE ALSO" \fBbobcat\fP(7), \fBbigint\fP(3bobcat), \fBecdh\fP(3bobcat), \fBisymcryptstream\fP(3bobcat), \fBosymcryptstream\fP(3bobcat) .PP .SH "BUGS" None Reported\&. .PP .SH "BOBCAT PROJECT FILES" .PP .IP o \fIhttps://fbb\-git\&.gitlab\&.io/bobcat/\fP: gitlab project page; .IP o \fIbobcat_6\&.04\&.00\-x\&.dsc\fP: detached signature; .IP o \fIbobcat_6\&.04\&.00\-x\&.tar\&.gz\fP: source archive; .IP o \fIbobcat_6\&.04\&.00\-x_i386\&.changes\fP: change log; .IP o \fIlibbobcat1_6\&.04\&.00\-x_*\&.deb\fP: debian package containing the libraries; .IP o \fIlibbobcat1\-dev_6\&.04\&.00\-x_*\&.deb\fP: debian package containing the libraries, headers and manual pages; .PP .SH "BOBCAT" Bobcat is an acronym of `Brokken\(cq\&s Own Base Classes And Templates\(cq\&\&. .PP .SH "COPYRIGHT" This is free software, distributed under the terms of the GNU General Public License (GPL)\&. .PP .SH "AUTHOR" Frank B\&. Brokken (\fBf\&.b\&.brokken@rug\&.nl\fP)\&. .PP