.TH "FBB::ECDH" "3bobcat" "2005\-2023" "libbobcat\-dev_6\&.04\&.00" "Elliptic Curve Diffie\-Hellman" .PP .SH "NAME" FBB::ECDH \- Elliptic Curve 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::ECDH\fP computes shared keys (shared secrets) applying elliptic keys to 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 an elliptic curve specification and a public key, which may be shared over insecure media\&. .PP The Diffie\-Hellman algorithm is commonly used to compute a shared key which is then used to encrypt information sent between two parties\&. .PP One party, which in this man\-page is called the \fIinitiator\fP, specifies at construction time an elliptic curve, constructs a public and private key, and writes the public key in hexadecimal big\-endian form, followed by the name of the used elliptic curve to file\&. The initiator\(cq\&s private key is separately written to file, as the private key is required for computating the shared key\&. Encryption may be used when writing the private key to file\&. .PP Next the initiator passes the file containing the initiator\(cq\&s public key and the name of the used elliptic curve to the other party, which in this man\-page is called the \fIpeer\fP\&. .PP The peer, having received the initiator\(cq\&s (public key) file constructs an \fBFBB::ECDH\fP object\&. The peer\(cq\&s \fIECDH\fP constructor computes the peer\(cq\&s public and private key, writes the peer\(cq\&s public key to file, and constructs the shared key\&. Once the peer\(cq\&s \fIECDH\fP object has been constructed the peer can write the shared key to file\&. The peer\(cq\&s private key may optionally also be written to file, but that\(cq\&s optional, as the peer\(cq\&s private key is not required for subsequent computations\&. Encryption may also be used when writing the peer\(cq\&s private key to file\&. .PP The file containing the peer\(cq\&s public key is then sent to the initator\&. The initator constructs an \fIECDH\fP object specifying the names of the used elliptic curve, of the file containing the initiator\(cq\&s private key, and the name of the file containing the peer\(cq\&s public key\&. Once this \fIECDH\fP object has been constructed the peer may write the shared key to file\&. .PP The initiator and peer\(cq\&s shared keys are identical and can be used for symmetric encryption of sensitive information shared between the initiator and the peer\&. .PP \fIFBB::Exception\fPs are thrown if the \fIECDH\fP constructors or members cannot complete their tasks\&. .PP \fBPerfect Forward Secrecy and Ephemeral Diffie Hellman\fP .PP The initiator and peer may decide not to save their private information once they have constructed their shared keys, resulting in \fIPerfect Forward Secrecy\fP and \fIEphemeral Diffie Hellman\fP\&. Here, this 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 procedure described in the previous section, the private keys are not saved on files, and the process constructing the initiator\(cq\&s \fIECDH\fP object may not terminate, but must remain active until the peer\(cq\&s public key has been received\&. Once the initiator\(cq\&s process has constructed the public key that key is encrypted using the common secret, and is then sent to the peer\&. Alternatively, the initiator\(cq\&s private key may temporarily be stored in shared memory or may temporarily be stored encrypted on file\&. .IP o The peer, having received the initiator\(cq\&s public key, constructs the shared secret, encrypts the peer\(cq\&s public key, and sends the encrypted public key to the initiator\&. .IP o The initiator upon receipt of the peer\(cq\&s public key, computes the shared key, either by continuing the temporarily suspended construction process or by retrieving the shared key from memory or file, removing the storage (memory or file) thereafter\&. .IP o Since the private keys and the public keys are not stored or kept on files the shared keys 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 normally not used for encrypting documents\&. Instead, it is used to obtain a key that is used for symmetric encryption methods like 3DES or CBC\&. These symmetric encryption methods are available through, e\&.g\&., Bobcats\(cq\& \fIISymCryptStream\fP and \fIOSymCryptStream\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 "ENUMERATIONS" The class \fIECDH\fP defines two enumerations, each having one defined value\&. The enumberations are used to select specific overloaded versions of the \fIECDH\fP constructors or \fIset\fP members: .IP o The t(enum TheInitiator) has value \fIInitiator\fP and is used to select overloaded versions meant for the initiator; .IP o The t(enum ThePeer) has value \fIPeer\fP and is used to select overloaded versions meant for the peer\&. .PP .SH "CONSTRUCTORS" .PP .IP o \fBECDH()\fP: .br The default constructor is available merely constructing a valid object\&. It also prepares a map of all elliptic curves predefined by \fIopenSSL\fP\&. As all other constructors use default constructor delegation the map is also available after calling the other constructors; .IP .IP o \fBECDH(TheInitiator init, std::string const &curveName, std::string const &initPubFname)\fP: .br This constructor initializes the \fIECDH\fP object to be used by the initiator, constructing the initiator\(cq\&s private and public keys using the elliptic curve specified by \fIcurveName\fP (e\&.g\&., \fIsecp384r1\fP, see also \fIoperator<<\fP below)\&. The initiator\(cq\&s public key (in big\-endian hexadecimal format) and \fIcurveName\fP are written to \fIinitPubFname\fP; .IP This constructor should be called by the initiator to start the Diffie\-Hellman shared key computation procedure; .IP .IP o \fBECDH(ThePeer peer, std::string const &initPubFname, std::string const &peerPubFname)\fP: .br This constructor is used by the peer, having received the initiator\(cq\&s public info on the file \fIinitPubFname\fP\&. It constructs the peer\(cq\&s private and public keys as well as the shared key\&. The peer\(cq\&s public key (in big\-endian hexadecimal format) is written to \fIpeerPubFname\fP, which file is then be sent to the initiator; .IP .IP o \fBECDH(std::string const &curveName, std::string const &peerPubFname, std::string const &initSecFname, std::string const passphrase = \(dq\&\(dq\&)\fP: .br Once the initiator has received the peer\(cq\&s public key (in the file \fIpeerPubFname\fP) this constructor constructs the initiator\(cq\&s version of the shared key\&. Here, the initiator has previously saved the initiator\(cq\&s private key to \fIinitSecFname\fP, optionally using encryption\&. If encryption was used then the then used passphrase must also be specified when using this constructor\&. .PP The move constructor (and move assignment operator) is available\&. .PP .SH "MEMBER FUNCTIONS" .IP o \fBstd::string const &curve() const\fP: .br The used elliptic curve is returned; .IP .IP o \fBstd::string privKey() const\fP: .br The big\-endian hex\-formatted private key is returned, prefixed by a line containing \fIhex\fP; .IP .IP o \fBvoid privKey(std::string const &privKeyFname, std::string passphrase) const\fP: .br The private private key is encrypted using the \fIAES\-256\-GCM\fP encryption algorithm, using passphrase \fIpassphrase\fP\&. It is then written to \fIprivKeyFname\fP, prefixed by a line containing \fIencrypted\fP\&. The string \fIpassphrase\fP must consist of at least five characters, and may contain multiple words; .IP .IP o \fBstd::string const &pubKey() const\fP: .br The public key is returned as a big\-endian hexadecimal string; .IP .IP o \fBvoid set(TheInitiator init, std::string const &curveName, std::string const &initPubFname)\fP: .br This member should be called by the initiator, constructing the initiator\(cq\&s private and public keys using the elliptic curve specified by \fIcurveName\fP\&. The initiator\(cq\&s public key (in big\-endian hexadecimal format) and \fIcurveName\fP are written to \fIinitPubFname\fP\&. This member is automatically called by the constructor having the same parameters, but it may also explicitly called after using the default constructor; .IP .IP o \fBvoid set(ThePeer peer, std::string const &initPubFname, std::string const &peerPubFname)\fP: .br This member should be called by the peer, having received the initiator\(cq\&s public info on the file \fIinitPubFname\fP\&. It constructs the peer\(cq\&s private and public keys as well as the shared key\&. The peer\(cq\&s public key (in big\-endian hexadecimal format) is written to \fIpeerPubFname\fP, which file is then be sent to the initiator\&. This member is automatically called by the constructor having the same parameters, but it may also explicitly called after using the default constructor; .IP .IP o \fBvoid set(std::string const &curveName, std::string const &peerPubFname, std::string const &initSecFname, std::string const passphrase = \(dq\&\(dq\&)\fP: .br This member should be called by the initiator, once the peer\(cq\&s public key (in the file \fIpeerPubFname\fP) has been received\&. It computes the initiator\(cq\&s version of the shared key\&. When using this member the initiator has previously saved the initiator\(cq\&s private key to \fIinitSecFname\fP, optionally using encryption\&. If encryption was used then the then used passphrase must also be specified as this member\(cq\&s last argument\&. .IP .IP o \fBstd::string const &sharedKey() const\fP: .br This member returns the computed shared key (in big\-endian hexadecimal format); .IP .IP o \fBstd::string const &sharedKey(std::string const &peerPubFname)\fP: .br Instead of using the \fIset(std::string const &curveName, \&.\&.\&.)\fP member or the \fIECDH(std::string const &curveName, \&.\&.\&.)\fP constructor, the initiator may also merely call the \fIset(TheInitiator init, \&.\&.\&.)\fP member or the \fIECDH(TheInitiator init, \&.\&.\&.)\fP constructor, suspending the process in which they are called until the file containing the peer\(cq\&s public key has been received\&. Then, this member can be called by the constructed \fIECDH\fP object to obtain the initiator\(cq\&s shared key\&. The advantage of using this member is that the initiator does not have to save the initiator\(cq\&s private key\&. .PP .SH "OVERLOADED OPERATOR" .PP .IP o \fBstd::ostream &operator<<(ostream &out, ECDH const &ecdh)\fP: .br The (alphabetically ordered) currently available elliptic curves and their associated comment is written to \fIout\fP, one elliptic curve on a separate line\&. .PP .SH "EXAMPLE" .PP Start the program with one of the following arguments: .IP o curves: show the available elliptic curves on \fIcout\fP; .IP o init: compute the initiator\(cq\&s public/secret keys writing them to \fIinit\&.pub\fP and \fIinit\&.sec\fP; .IP o peer: compute the peer\(cq\&s public/secret keys writing them to \fIpeer\&.pub\fP and \fIpeer\&.sec\fP, compute the peer\(cq\&s shared key (\fIpeer\&.shared\fP); .IP o priv: compute the initiator\(cq\&s shared key (\fIinit\&.shared\fP) after making \fIpeer\&.pub\fP available in a separate process, using a single initiator process\&. .IP o shared: compute the initiator\(cq\&s shared key (\fIinit\&.shared\fP) using a separate initiator process\&. .PP .nf #include \(dq\&main\&.ih\(dq\& int main(int argc, char **argv) try { if (argc == 1) { usage(path{ argv[0] }\&.filename()\&.string()); return 0; } if (\(dq\&curves\(dq\&s == argv[1]) // show supported ECDH curves\&. cout << ECDH{}; else if (\(dq\&init\(dq\&s == argv[1]) // initiator key construction { // write the file containing // the curve + public key ECDH ecdh{ ECDH::Initiator, \(dq\&secp384r1\(dq\&, \(dq\&init\&.pub\(dq\& }; // save the initiator\(cq\&s // private key ecdh\&.privKey(\(dq\&init\&.sec\(dq\&, \(dq\&use your passphrase\(dq\&); // not using encryption: // auto initSec = Exception::factory(\(dq\&init\&.sec\(dq\&); // initSec << ecdh\&.privKey() << \(cq\&\en\(cq\&; } else if (\(dq\&priv\(dq\&s == argv[1]) // initiator key construction { // write the file containing // the curve + public key ECDH ecdh{ ECDH::Initiator, \(dq\&secp384r1\(dq\&, \(dq\&init\&.pub\(dq\& }; cout << \(dq\&wait for the peer\(cq\&s public key\&. \(dq\& \(dq\&Press Enter to continue\&.\&.\&. \(dq\&; cin\&.ignore(100, \(cq\&\en\(cq\&); // written to file auto initShared = Exception::factory(\(dq\&init\&.shared\(dq\&); initShared << ecdh\&.sharedKey(\(dq\&peer\&.pub\(dq\&) << \(cq\&\en\(cq\&; } else if (\(dq\&peer\(dq\&s == argv[1]) // peer\(cq\&s key construction { // write the peer\(cq\&s public key ECDH ecdh{ ECDH::Peer, \(dq\&init\&.pub\(dq\&, \(dq\&peer\&.pub\(dq\& }; // save the peer\(cq\&s private // key (although not needed) auto out = Exception::factory(\(dq\&peer\&.sec\(dq\&); out << ecdh\&.privKey() << \(cq\&\en\(cq\&; out = Exception::factory(\(dq\&peer\&.shared\(dq\&); out << ecdh\&.sharedKey() << \(cq\&\en\(cq\&; } else if (\(dq\&shared\(dq\&s == argv[1]) // the initiator\(cq\&s shared key { // construction ECDH ecdh{ \(dq\&secp384r1\(dq\&, \(dq\&peer\&.pub\(dq\&, \(dq\&init\&.sec\(dq\&, \(dq\&use your passphrase\(dq\& }; auto initShared = Exception::factory(\(dq\&init\&.shared\(dq\&); initShared << ecdh\&.sharedKey() << \(cq\&\en\(cq\&; // written to file } else { usage(path{ argv[0] }\&.filename()\&.string()); return 1; } } catch (exception const &exc) { cerr << \(dq\&Error: \(dq\& << exc\&.what() << \(cq\&\en\(cq\&; return 1; } catch (\&.\&.\&.) // and handle an unexpected exception { cerr << \(dq\&unexpected exception\en\(dq\&; return 1; } .fi .PP .SH "FILES" \fIbobcat/ecdh\fP \- defines the class interface .PP .SH "SEE ALSO" \fBbobcat\fP(7), \fBbigint\fP(3bobcat), \fBdiffiehellman\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