I need to encrypt single block of AES. I cant use any modes like CBC and other. Every example what i have seen use streaming modes.
EDIT:
ok, i did it in the next manner, but i really dislike this try.
void dec(const byte *key, const byte* xblock, const byte *cipher, byte *plain) {
AESDecryption d;
try {
const NameValuePairs &nvp = MakeParameters("", 0);
d.UncheckedSetKey(key, 16, nvp);
d.ProcessAndXorBlock(cipher, xblock, plain);
}
catch(...) {}
}
AES in ECB mode is identical to single block encryption, except that you can feed it multiple blocks.
If you've got only CBC mode encryption available you can use the first block of a CBC encrypt using a (block sized) IV containing bytes all valued zero. The same goes for counter (CTR) mode encryption and a nonce containing bytes all valued zero (the counter only increases after the first block encrypt).
Crypto++ seems to be a higher level Crypto API, so it is better not to directly call the AES implementation directly.
Related
Hey I'm looking for some explanation regarding
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
const AES_KEY *key, unsigned char *ivec, int *num, int enc)
I understand the straightforward variables like
in is our input buffer
out is our output buffer
length is size of our input/number of bytes of input buffer
key is pointer to our key which we set by AES_set_encrypt_key
enc is the mode we want(whether encryption or decryption)
However, I don't understand what ivec and num do.
I just know (might be wrong) is that ivec stands for initial vector and another thing in a code that i found online there was a comment:
/* set where on the 128 bit encrypted block to begin encryption*/. At first, I thought this left gaps of unencrypted data in the midst of encrypted one, but that wasn't the case when I looked at the byte values while debugging and printing values.
ivec is an Initialisation Vector and commonly written as IV. The keyword is the probabilistic encryption;
If the encryption is not probabilistic then when you re-encrypt a message under the same key, you will get the same result and an eavesdropper will notice this. This is a simple attack, in some modes, this is more catastrophic like CTR mode where encryption of two messages under the same IV can cause loss of confidentiality.
In CFB mode, if you encrypt two different messages then the first blocks are under attack where the attacker gets x-or of the messages.
One should generate random IV's per message since the IV must be unpredictable for CFB mode ( as in CBC mode).
Note that, you need to send the IV to the receiver so that the decryption works. The IV need not be secret, one can prepend it to cyphertext.
Don't forget that, those are archaic mode of operation, in modern cryptography we prefer authenticated encryption modes like AES-GCM, AES-CCM, and ChaCha20-Poly1305.
And, the key is still secure even if you don't generate random per message!
I have a simple program that encrypts and decrypts text from input gotten from a text file. When I encrypt and decrypt in one cycle, I get the desired result, but if I encrypt, close application then re-run application, this time decrypt, the process fails.
The decryption snippet looks like this :
string decoded, plainText;
string fileData((istreambuf_iterator<char>(fileDecrypt)), (istreambuf_iterator<char>()));
ECB_Mode<AES>::Decryption decryption;
decryption.SetKey((byte*)key.c_str(), sizeof(key));
StringSource(fileData, true, new HexDecoder(new StringSink(decoded)));
StringSource(decoded, true, new StreamTransformationFilter(decryption, new StringSink(plainText)));
When I run debugger in VS2010, I get error on the last line
StringSource(decoded, true, new StreamTransformationFilter(decryption, new StringSink(plainText)));
When I wrap a try-catch block around decrypt function, I get this error
StreamTransformationFilter: invalid PKCS #7 block padding found
Not sure why it works if I encrypt and decrypt in one build, but fail if I try to decrypt without first encrypting first on the same run.
ECB_Mode<AES>::Decryption decryption;
ECB mode operates on a full block size, and no padding is required.
You can pad it, but it does not look like you are doing so. The caveat is the plain text must be a multiple of 16, which is AES's blocksize.
When I wrap a try-catch block around decrypt function, I get this
error
StreamTransformationFilter: invalid PKCS #7 block padding found
That's because you are padding it in:
StreamTransformationFilter(decryption, new StringSink(...)).
StreamTransformationFilter has a padding parameter. As you probably realize, it is BlockPaddingScheme::PKCS_PADDING
Try:
ECB_Mode<AES>::Decryption decryption;
decryption.SetKey((byte*)key.data(), key.size());
std::string plainText;
StreamTransformationFilter filter(decryption, new StringSink(plainText),
StreamTransformationFilter::NO_PADDING);
FileSource fs(filename.c_str(), true, new HexDecoder(new Redirector(filter)));
...
Other errata:
ECB_Mode<AES>::Decryption decryption;
decryption.SetKey((byte*)key.c_str(), sizeof(key));
sizeof(key) is wrong. Use 16, 24, or 32. If the std::string is properly sized, then you can use key.size().
And name you objects. I've seen GCC generate bad code with Crypto++:
ECB_Mode<AES>::Decryption decryption;
StringSource ss1(fileData, ...);
StringSource ss2(decoded, ...);
And a quick warning....
ECB mode is usually wrong. I'm not saying it is in this case, or that you are wrong. But you might want to have a look at EAX mode, GCM mode or CCM mode. My apologies if this is more than it seems.
Even better, use a scheme like Elliptic Curve Integrated Encryption Scheme (ECIES) or Discrete Logarithm Integrated Encryption Scheme (DLIES). The schemes are IND-CCA, which is a very strong notion of security.
When using ECIES or DLIES, your problem reduces to sharing the public keys. But you have that problem now with the symmetric keys, so its a lateral move for key distribution, and a win for encryption.
When using Botan encryption with botansqlite3, what are the optimal configuration settings for performance?
OR
How can I configure Botansqlite3 to use CAST5?
I am currently using AES and it is too slow. My use case is a game.
I am looking for weak or moderate encryption to protect my game's data (not end user data) so security is less of a consideration than performance.
Here is my current BotanSqlite3 codec.h
/*These constants can be used to tweak the codec behavior as follows */
//BLOCK_CIPHER_STR: Cipher and mode used for encrypting the database
//make sure to add "/NoPadding" for modes that use padding schemes
const string BLOCK_CIPHER_STR = "Twofish/XTS";
//PBKDF_STR: Key derivation function used to derive both the encryption
//and IV derivation keys from the given database passphrase
const string PBKDF_STR = "PBKDF2(SHA-160)";
//SALT_STR: Hard coded salt used to derive the key from the passphrase.
const string SALT_STR = "&g#nB'9]";
//SALT_SIZE: Size of the salt in bytes (as given in SALT_STR)
const int SALT_SIZE = 64/8; //64 bit, 8 byte salt
//MAC_STR: CMAC used to derive the IV that is used for db page
//encryption
const string MAC_STR = "CMAC(Twofish)";
//PBKDF_ITERATIONS: Number of hash iterations used in the key derivation
//process.
const int PBKDF_ITERATIONS = 10000;
//KEY_SIZE: Size of the encryption key. Note that XTS splits the key
//between two ciphers, so if you're using XTS, double the intended key
//size. (ie, "AES-128/XTS" should have a 256 bit KEY_SIZE)
const int KEY_SIZE = 512/8; //512 bit, 64 byte key. (256 bit XTS key)
//IV_DERIVATION_KEY_SIZE: Size of the key used with the CMAC (MAC_STR)
//above.
const int IV_DERIVATION_KEY_SIZE = 256/8; //256 bit, 32 byte key
//This is definited in sqlite.h and very unlikely to change
#define SQLITE_MAX_PAGE_SIZE 32768
I believe that I need to find replacements for BLOCK_CIPHER_STR, PBKDF_STR, MAC_STR, KEY_SIZE and IV_DERIVATION_KEY_SIZE to reconfigure BotanSqlite3 to use a different codec.
I found a extensive comparison test of Botan codec performance here:
http://panthema.net/2008/0714-cryptography-speedtest-comparison/crypto-speedtest-0.1/results/cpu-sidebyside-comparison-3x2.pdf#page=5
However, the testing was done with Botan directly, not botansqlite3 as I intend to use it. Looking at the charts, a good candidate appears to be CAST5 from a performance perspective.
The database in question is 300KB, mostly INTEGER fields with some text blobs.
I am configuring Botan as suggested by OlivierJG of botansqlite3 fame, using the amalgamation
'./configure.py --no-autoload --enable-modules=twofish,xts,pbkdf2,cmac,sha1 --gen-amalgamation --cc=msvc --os=win32 --cpu=x86 --disable-shared --disable-asm'
References:
http://github.com/OlivierJG/botansqlite3 - botansqlite3 is an encryption codec for SQLite3 that can use any algorithms in Botan for encryption
http://www.sqlite.org - sqlite3 is a cross-platform SQL database
http://botan.randombit.net/ - botan is a C++ encryption library with support for a number of codecs
You can get CAST-128 (or as I was calling it, CAST5) to work, it is a block cipher.
The best bet is the above with different configuration of key size.
Twofish is pretty fast.
Thank you to 'Olivier JG' for all the excellent code.
I've got the stream to decrypt. I divide it into blocks and pass each block to the method below. The data I need to decrypt is encrypted by 16 - bytes blocks and if the last block is less than 16, then all the rest bytes are filled by padding. Then in the moment of decryption I'm getting my last block result as the value including these additional padding bytes. How can I determine the length of original data and return only it or determine the padding bytes and remove them, considering different paddings could be used?
void SymmetricAlgorithm::Decrypt(byte* buffer, size_t dataBytesSize) {
MeterFilter meter(new ArraySink(buffer, dataBytesSize));
CBC_Mode<CryptoPP::Rijndael>::Decryption dec(&Key.front(), Key.size(), &IV.front());
StreamTransformationFilter* filter = new StreamTransformationFilter(dec, new Redirector(meter), PKCS_PADDING);
ArraySource(buffer, dataBytesSize, true, filter);
dec.Resynchronize(&IV.front());
}
Now I'm trying with PKCS_PADDING and Rijndael, but in general I might need work with any algorithm and any padding.
I divide it into blocks and pass each block to the method below
In this case, you might consider calling ProcessBlock directly:
CBC_Mode<Rijndael>::Decryption dec(...);
// Assume 'b' is a 16-byte block
dec.ProcessBlock(b);
The block is processed in place, so its destructive. You will also be responsible for processing the last block, including the removal of padding.
By blocking and removing padding, you are doing the work of the StreamTransformationFilter (and friends).
As it happens, I found what I needed occasionally in the example from this question.
Appreciate your help, Gabriel L., but I didn't want make my method not to use padding at all. Sorry for unclear explanations, I wanted to extract plain data from decrypted data, which includes padding symbols. And the bold row in this code shows how to find out plain data bytes count.
void SymmetricAlgorithm::Decrypt(byte* buffer, size_t dataBytesSize) {
MeterFilter meter(new ArraySink(buffer, dataBytesSize));
CBC_Mode<CryptoPP::Rijndael>::Decryption dec(&Key.front(), Key.size(), &IV.front());
StreamTransformationFilter* filter = new StreamTransformationFilter(dec, new Redirector(meter), PKCS_PADDING);
ArraySource(buffer, dataBytesSize, true, filter);
int t = meter.GetTotalBytes(); //plain data bytes count
dec.Resynchronize(&IV.front());
}
I need to encrypt single block of AES. I cant use any modes like CBC and other. Every example what i have seen use streaming modes.
EDIT:
ok, i did it in the next manner, but i really dislike this try.
void dec(const byte *key, const byte* xblock, const byte *cipher, byte *plain) {
AESDecryption d;
try {
const NameValuePairs &nvp = MakeParameters("", 0);
d.UncheckedSetKey(key, 16, nvp);
d.ProcessAndXorBlock(cipher, xblock, plain);
}
catch(...) {}
}
AES in ECB mode is identical to single block encryption, except that you can feed it multiple blocks.
If you've got only CBC mode encryption available you can use the first block of a CBC encrypt using a (block sized) IV containing bytes all valued zero. The same goes for counter (CTR) mode encryption and a nonce containing bytes all valued zero (the counter only increases after the first block encrypt).
Crypto++ seems to be a higher level Crypto API, so it is better not to directly call the AES implementation directly.