.TH "FBB::EncryptBuf" "3bobcat" "2005\-2020" "libbobcat\-dev_5\&.07\&.00" "Encrypt information" .PP .SH "NAME" FBB::EncryptBuf \- Encrypts information using various methods into a std::ostream .PP .SH "SYNOPSIS" \fB#include \fP .br Linking option: \fI \-lbobcat \-lcrypto\fP .PP .SH "DESCRIPTION" \fBFBB::EncryptBuf\fP objects are \fBstd::streambuf\fP objects that can be used to initialize \fIstd::ostream\fP objects\&. .PP All information inserted into such a \fIstd::ostream\fP is encrypted and written into an \fIstd::ostream\fP that is given as argument to \fIEncryptBuf\fP\(cq\&s constructor\&. .PP All encryption methods supported by the OpenSSL library that can be selected by name may be used by \fIEncryptBuf\fP objects\&. To select a particular encryption method an identifier is passed to the constructor\&. E\&.g\&., \fI\(dq\&aes\-128\-cbc\(dq\&\fP indicating the AES (Rijndael) method, using 128 bit sized keys and blocks using `cbc\(cq\& mode (see below for an explanation)\&. .PP Most modes use \fIinitialization vectors\fP\&. Unless provided at construction time \fIEncryptBuf\fP objects create random initialization vectors\&. The initialization vector that is actually used can be obtained from the \fIEncryptBuf\fP object\&. This is important, as the matching decryption object needs to know the initialization vector that was used when encrypting the data\&. Initialization vectors are not considered confidential and they can be sent in the clear to the decryption object\&. What \fIis\fP important, though, is that they contain random data when used `for real\(cq\&\&. When an initialization vector is specified that is shorter than expected by the encryption method it is automatically extended with 0\-bytes to the required length\&. .PP Block ciphers use one of the following four encryption modes: .IP o \fBCBC (Cipher Block Chaining)\fP: .br The first block is XOR\-ed by the initialization vector and then encrypted using the specified method\&. Subsequent blocks are XOR\-ed by the encrypted version of the preceding block\&. Due to the initialization vector dictionary attacks are infeasible, as long as the initialization vector is truly random\&. .IP o \fBECB (Electronic Code Book)\fP: .br Each block is encrypted by itself, using the specified encryption method\&. Although an \fIinitialization vector\fP may be specified, it is not used\&. This method is susceptible to dictionary attacks and should therefore be avoided, unless you know what you\(cq\&re doing\&. .IP o \fBCFB (Cipher Feednack)\fP: .br This method allows a block cipher to be used as a stream cipher\&. It uses an initialization vector, which should be unique and random for each new stream of data that is encrypted using the method\&. Encryption can only start after the first data block has been received\&. .IP o \fBOFB (Output Feednack)\fP: .br This is an alternative way to use a block cipher as a stream cipher\&. It is somewhat more susceptible to traditional data manipulation attacks, which can usually be thwarted when a message authentication code is added to the information as well\&. Like CFB it uses an initialization vector, which should again be unique and random for each new stream of data that is encrypted\&. .PP The following table presents an overview of methods that are currently available\&. Methods for which the block size is specified as N\&.A\&. are stream ciphers; other methods are block ciphers: .TS tab(~); ----- lllll lllll ----- lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll ----- lllll lllll lllll lllll lssss ----- lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll lllll ----- lllll lllll lllll lllll lssss ----- lllll lllll lllll lllll ----- lllll ----- lllll lllll lllll lllll ----- lllll lllll lllll lllll lssss lssss ----- lllll lllll lllll lllll lssss ----- lllll lssss ----- lllll lssss ----- lllll lssss lssss ----- lllll lssss ----- lllll lllll lllll lllll lssss lssss ----- c. method~keysize~blocksize~mode~identifier ~(bytes)~(bytes)~ AES~16~8~CBC~\(dq\&aes\-128\-cbc\(dq\& ~ ~ ~EBC~\(dq\&aes\-128\-ecb\(dq\& ~ ~ ~CFB~\(dq\&aes\-128\-cfb\(dq\& ~ ~ ~OFB~\(dq\&aes\-128\-ofb\(dq\& ~24~24~CBC~\(dq\&aes\-192\-cbc\(dq\& ~ ~ ~EBC~\(dq\&aes\-192\-ecb\(dq\& ~ ~ ~CFB~\(dq\&aes\-192\-cfb\(dq\& ~ ~ ~OFB~\(dq\&aes\-192\-ofb\(dq\& ~32~32~CBC~\(dq\&aes\-256\-cbc\(dq\& ~ ~ ~EBC~\(dq\&aes\-256\-ecb\(dq\& ~ ~ ~CFB~\(dq\&aes\-256\-cfb\(dq\& ~ ~ ~OFB~\(dq\&aes\-256\-ofb\(dq\& BLOWFISH~16~8~CBC~\(dq\&bf\-cbc\(dq\& ~ ~ ~EBC~\(dq\&bf\-ecb\(dq\& ~ ~ ~CFB~\(dq\&bf\-cfb\(dq\& ~ ~ ~OFB~\(dq\&bf\-ofb\(dq\& max key length is 56 bytes, 16 generally used~ CAMELLIA~16~16~CBC~\(dq\&camellia\-128\-cbc\(dq\& ~ ~ ~EBC~\(dq\&camellia\-128\-ecb\(dq\& ~ ~ ~CFB~\(dq\&camellia\-128\-cfb\(dq\& ~ ~ ~OFB~\(dq\&camellia\-128\-ofb\(dq\& ~24~~CBC~\(dq\&camellia\-192\-cbc\(dq\& ~ ~ ~EBC~\(dq\&camellia\-192\-ecb\(dq\& ~ ~ ~CFB~\(dq\&camellia\-192\-cfb\(dq\& ~ ~ ~OFB~\(dq\&camellia\-192\-ofb\(dq\& ~32~~CBC~\(dq\&camellia\-256\-cbc\(dq\& ~ ~ ~EBC~\(dq\&camellia\-256\-ecb\(dq\& ~ ~ ~CFB~\(dq\&camellia\-256\-cfb\(dq\& ~ ~ ~OFB~\(dq\&camellia\-256\-ofb\(dq\& CAST~16~8~CBC~\(dq\&cast\-cbc\(dq\& ~ ~ ~EBC~\(dq\&cast\-ecb\(dq\& ~ ~ ~CFB~\(dq\&cast\-cfb\(dq\& ~ ~ ~OFB~\(dq\&cast\-ofb\(dq\& min key length is 5 bytes, max is shown~ DES~8~8~CBC~\(dq\&des\-cbc\(dq\& ~ ~ ~EBC~\(dq\&des\-ebc\(dq\& ~ ~ ~CFB~\(dq\&des\-cfb\(dq\& ~ ~ ~OFB~\(dq\&des\-ofb\(dq\& DESX~8~8~CBC~\(dq\&desx\-cbc\(dq\& 3DES~16~8~CBC~\(dq\&des\-ede\-cbc\(dq\& ~ ~ ~EBC~\(dq\&des\-ede\(dq\& ~ ~ ~CFB~\(dq\&des\-ede\-cfb\(dq\& ~ ~ ~OFB~\(dq\&des\-ede\-ofb\(dq\& 3DES~24~8~CBC~\(dq\&des\-ede3\-cbc\(dq\& ~ ~ ~EBC~\(dq\&des\-ede3\(dq\& ~ ~ ~CFB~\(dq\&des\-ede3\-cfb\(dq\& ~ ~ ~OFB~\(dq\&des\-ede3\-ofb\(dq\& Key bytes 9\-16 define the 2nd key, bytes 17\-24~ define the 3rd key~ RC2~16~8~CBC~\(dq\&rc2\-cbc\(dq\& ~ ~ ~EBC~\(dq\&rc2\-ecb\(dq\& ~ ~ ~CFB~\(dq\&rc2\-cfb\(dq\& ~ ~ ~OFB~\(dq\&rc2\-ofb\(dq\& Key length variable, max\&. 128 bytes, default length is shown~ RC2\-40~5~8~~\(dq\&rc2\-40\-cbc\(dq\& obsolete: avoid~ RC2\-64~8~8~~\(dq\&rc2\-64\-cbc\(dq\& obsolete: avoid~ RC4~16~N\&.A\&.~~\(dq\&rc4\(dq\& Key length is variable, max\&. 256 bytes\&. default length is shown~ Encrypt again to decrypt\&. Don\(cq\&t use \fIDecryptBuf\fP~ RC4\-40~5~N\&.A\&.~~\(dq\&rc4\-40\(dq\& obsolete: avoid~ RC5~16~8~CBC~\(dq\&rc5\-cbc\(dq\& ~ ~ ~EBC~\(dq\&rc5\-ecb\(dq\& ~ ~ ~CFB~\(dq\&rc5\-cfb\(dq\& ~ ~ ~OFB~\(dq\&rc5\-ofb\(dq\& Key length variable, max\&. 256 bytes, rounds 8, 12 or 16,~ default # rounds is 12~ .TE .PP The RC4 stream cipher is subject to a well\-known attack (cf\&. http://www\&.wisdom\&.weizmann\&.ac\&.il/~itsik/RC4/Papers/Mantin1\&.zip) unless the initial 256 bytes produced by the cipher are discarded\&. .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" \fBFBB::CryptBuf\fP, in turn inheriting from \fBstd::streambuf\fP .PP .SH "CONSTRUCTOR/DESTRUCTOR" .IP o \fBEncryptBuf(std::ostream &outStream, char const *type, std::string const &key, std::string const &iv, size_t bufsize = 1024)\fP: .br This constructor initializes the \fIEncryptBuf\fP object preparing it for the encryption algorithm specified with \fItype\fP\&. The encryption algorithms that can be used are listed in the abovementioned table\&. E\&.g\&., to use the AES method on 24 bit keys and blocks in CBC mode specify \fI\(dq\&aes\-192\-cbc\(dq\&\fP\&. The \fIkey\fP parameter refers to the key to be used, the \fIiv\fP parameter refers to the initialization vector to use\&. Both \fIkey\fP and \fIiv\fP may contain non\-displayable characters\&. When \fIiv\&.length()\fP is zero it will be filled by the \fIEncryptBuf\fP object with random data\&. When the \fIiv\fP is too small for the requested method it is expanded by adding the required number of zero valued bytes\&. .IP The constructor throws an \fIFBB::Exception\fP exception if an encryption method is specified that is not supported by OpenSSL\&. .IP The constructor\(cq\&s first parameter refers to the \fIstd::ostream\fP to receive the encrypted information\&. Be aware of the fact that the encrypted information most likely contains non\-displayable characters\&. .IP The \fIbufsize\fP argument specifies the size in bytes of the internal buffer used by \fIEncryptBuf\fP temporarily storing incoming characters\&. The provided default argument can most likely be kept as\-is\&. .IP .IP o \fB~EncryptBuf()\fP: .br Normally, once all information has been inserted into the encryption stream the \fIend\fP manipulator (see below) is inserted to complete the encryption process\&. Alternatively, the encryption process ends once the \fIEncryptBuf\(cq\&s\fP destructor is called\&. E\&.g\&., if \fIencStream\fP is the \fIstd::ostream\fP to receive the information to encrypt and \fIinStream\fP is the \fIstd::istream\fP containing the information to encrypt then .nf endStream << inStream\&.rdbuf(); .fi completes the decryption once \fIEncryptBuf\(cq\&s\fP destructor is called\&. Alternatively, .nf encStream << inStream\&.rdbuf() << end; .fi can be used to immediately complete the encryption process\&. .PP Copy and move constructors (and assignment operators) are not available\&. .PP .SH "MEMBER FUNCTIONS" .PP All members of \fBstd::streambuf\fP are available, as \fBFBB::EncryptBuf\fP inherits from this class\&. .PP .IP o \fBsize_t blockLength() const\fP: .br This member returns the block size (in bytes) that are used by the specified method\&. .IP .IP o \fBsize_t ivLength() const\fP: .br This member returns the size (in bytes) of the initialization vector that is used by the specified method\&. .IP .IP o \fBstd::string iv() const\fP: .br This member returns a reference to the initialization vector that is used by the specified method\&. Be advised that the initialization vector may contain non\-displayable characters\&. .IP .IP o \fBsize_t keyLength() const\fP: .br This member returns the size of the key (in bytes) that are used by the specified method\&. .IP .IP o \fBsize_t rounds() const\fP: .br This member can only be used with the RC5 encryption method to query the number of rounds of the algorithm\&. It returns the currently used number of rounds or 0 if the member is called for another encryption method than RC5\&. .IP .IP o \fBbool setRounds(size_t nRounds)\fP: .br This member can only be used with the RC5 encryption method to set the number of rounds of the algorithm to 8, 12 or 16\&. When the number of rounds were updated successfully the member returns \fItrue\fP\&. It returns \fIfalse\fP in other cases (e\&.g\&., called for other encryption methods than RC5 or the requested number of rounds differ from 8, 12 or 16)\&. .PP .SH "PROTECTED MEMBER" .IP o \fBEVP_CIPHER_CTX *cipherCtx()\fP: .br Classes derived from \fIEncryptBuf\fP may use this member to gain direct access to the \fIEVP_CIPHER_CTX\fP pointer used by the \fIEncryptBuf\fP object\&. This pointer is a pointer to an opaque structure used by many OpenSSL functions to set or query parameters of an encryption method\&. .PP .SH "EXAMPLE" .nf #include #include #include #include #include #include \(dq\&\&.\&./encryptbuf\(dq\& #include using namespace std; using namespace FBB; int main(int argc, char **argv) try { if (argc == 1) throw Exception(1) << \(dq\&1st arg: method, 2nd arg: key, 3rd arg: (opt): iv, \(dq\& \(dq\&stdin: file to encrypt (to stdout)\en\(dq\& \(dq\&e\&.g\&., driver aes\-128\-cbc somekey < driver\&.cc > /tmp/enc\en\(dq\&; string key(argv[2]); string iv; if (argc > 3) iv = argv[3]; EncryptBuf encryptbuf(cout, argv[1], key, iv, 50); ostream out(&encryptbuf); size_t ivLength = encryptbuf\&.iv()\&.length(); cerr << \(dq\&Block length: \(dq\& << encryptbuf\&.blockLength() << \(dq\&\en\(dq\& \(dq\&Key length: \(dq\& << encryptbuf\&.keyLength() << \(dq\&\en\(dq\& \(dq\&Max Key length: \(dq\& << EVP_MAX_KEY_LENGTH << \(dq\&\en\(dq\& \(dq\&actual IV length: \(dq\& << ivLength << \(dq\&\en\(dq\& \(dq\&IV =\en\(dq\&; OHexBuf ohb{ cerr, ivLength << 1 }; ostream outHex(&ohb); outHex << encryptbuf\&.iv(); cerr << \(cq\&\en\(cq\& << dec; out << cin\&.rdbuf() << eoi; } catch(exception const &err) { cerr << err\&.what() << endl; return 1; } .fi .PP To ignore the initial 256 bytes generated by the RC4 algorithm a simple wrapper class around the eventual output stream can be used\&. Here is an illustration: .nf #include #include class Skip256: public FBB::OFilterBuf { size_t d_count; public: Skip256(std::ostream &os) : OFilterBuf(os), d_count(0) {} private: virtual int overflow(int c) { if (d_count == 256) out()\&.put(c); else ++d_count; return c; } }; .fi Next, an \fISkip256\fP object is used to define an intermediate \fIstd::ostream\fP that is then passed to the \fIEncryptBuf\fP object\&. E\&.g\&., only showing the essential steps defining the \fIEncryptBuf\fP object: .nf Skip256 skip256(std::cout); std::ostream out(&skip256); EncryptBuf encryptbuf(out, \(dq\&rc4\(dq\&, key, \(dq\&\(dq\&); .fi .PP .SH "FILES" \fIbobcat/encryptbuf\fP \- defines the class interface .PP .SH "SEE ALSO" \fBbobcat\fP(7), \fBdecryptbuf\fP(3bobcat), \fBofilterbuf\fP(3bobcat), \fBstd::streambuf\fP .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_5\&.07\&.00\-x\&.dsc\fP: detached signature; .IP o \fIbobcat_5\&.07\&.00\-x\&.tar\&.gz\fP: source archive; .IP o \fIbobcat_5\&.07\&.00\-x_i386\&.changes\fP: change log; .IP o \fIlibbobcat1_5\&.07\&.00\-x_*\&.deb\fP: debian package containing the libraries; .IP o \fIlibbobcat1\-dev_5\&.07\&.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