ECB Mode
Documentation |
#include <cryptopp/modes.h>
|
ECB Mode is electronic codebook. ECB was originally specified by NIST in FIPS 81. The standard, issued in 1981, only offers confidentiality. Other modes, such as CCM and GCM, offer authenticated encryption which places an integrity assurance over the encrpyted data.
ECB mode does not use an initialization vector (IV). The plain text must be padded to the block size of the cipher. If you attempt to set an IV, Crypto++ will throw an exception, AlgorithmParametersBase: parameter IV not used. For additional information on this mode, see Block Cipher Modes of Operation.
Crypto++ offers several modes of operation, including ECB, CBC, OFB, CFB, CBC-CTS, CTR, XTS, CCM, EAX, GCM and OCB.
Note: if your project is using encryption alone to secure your data, encryption alone is usually not enough. Please take a moment to read Authenticated Encryption and consider using an algorithm or mode like CCM, GCM, EAX or ChaCha20Poly1305.
Sample Program
There are three sample programs for ECB mode. The samples use filters in a pipeline). Pipelining is a high level abstraction and it handles buffering input, buffering output and padding for you. The first sample shows the basic use of a pipeline. The second sample shows how to change padding. The third shows how to manually insert into a filter.
If you are benchmarking then you may want to visit Benchmarks | Sample Program . It shows you how to use StreamTransformation
and its ProcessString
method to process multiple blocks at a time. ProcessString
eventually calls BlockTransformation
and ProcessBlock
. Calling a cipher's ProcessString
or ProcessBlock
eventually call ProcessAndXorBlock
or AdvancedProcessBlocks
, and they are the lowest level API you can use.
AutoSeededRandomPool prng; SecByteBlock key(AES::DEFAULT_KEYLENGTH); prng.GenerateBlock( key, key.size() ); string plain = "ECB Mode Test"; string cipher, encoded, recovered; /*********************************\ \*********************************/ try { cout << "plain text: " << plain << endl; ECB_Mode< AES >::Encryption e; e.SetKey( key, key.size() ); // The StreamTransformationFilter adds padding // as required. ECB and CBC Mode must be padded // to the block size of the cipher. StringSource ss1( plain, true, new StreamTransformationFilter( e, new StringSink( cipher ) ) // StreamTransformationFilter ); // StringSource } catch( CryptoPP::Exception& e ) { cerr << e.what() << endl; exit(1); } /*********************************\ \*********************************/ // Pretty print cipher text StringSource ss2( cipher, true, new HexEncoder( new StringSink( encoded ) ) // HexEncoder ); // StringSource cout << "cipher text: " << encoded << endl; /*********************************\ \*********************************/ try { ECB_Mode< AES >::Decryption d; // ECB Mode does not use an IV d.SetKey( key, key.size() ); // The StreamTransformationFilter removes // padding as required. StringSource ss3( cipher, true, new StreamTransformationFilter( d, new StringSink( recovered ) ) // StreamTransformationFilter ); // StringSource cout << "recovered text: " << recovered << endl; } catch( CryptoPP::Exception& e ) { cerr << e.what() << endl; exit(1); }
A typical output is shown below. Note that each run will produce different results because the key and initialization vector are randomly generated.
$ ./Driver.exe key: 7D24A35BDFB017C9E8C5701A1BB4DBF6 plain text: ECB Mode Test cipher text: 84B2DD5EB092DACF246395B86F1D6725 recovered text: ECB Mode Test
When using a StreamTransformationFilter
, the filter will pad the plain text as required. This means 13 bytes of input will receive 3 bytes of padding (for a 128 bit block cipher). This also means 16 bytes of input will receive 16 bytes of PKCS padding, resulting in 32 bytes of cipher text. For the latter case, padding can be removed as follows.
StringSource ss( plain, true, new StreamTransformationFilter( e, new StringSink( cipher ), StreamTransformationFilter::NO_PADDING ) // StreamTransformationFilter ); // StringSource
To manually insert bytes into the filter, perform multiple Put
s. Though Get
is used below, a StringSink
could easily be attached and save the administrivia.
const size_t SIZE = 16 * 4; string plain(SIZE, 0x00); for(size_t i = 0; i < plain.size(); i++) plain[i] = 'A' + (i%26); ... ECB_Mode < AES >::Encryption encryption(key, sizeof(key), iv); StreamTransformationFilter encryptor(encryption, NULL); for(size_t j = 0; j < plain.size(); j++) encryptor.Put((byte)plain[j]); encryptor.MessageEnd(); size_t ready = encryptor.MaxRetrievable(); string cipher(ready, 0x00); encryptor.Get((byte*) &cipher[0], cipher.size());
Downloads
Blowfish-ECB-Filter.zip - Demonstrates encryption and decryption using Blowfish in ECB mode with filters
AES-ECB-Filter.zip - Demonstrates encryption and decryption using AES in ECB mode with filters