difference between the methods update() and dofinal() in cipher - security

I have read one article about difference between the methods update() and dofinal() in cipher.
It was about what will happend if we want to encrypt 4 Bytes Array, when the block size of the cipher is for example 8 Bytes. If we call update here it will return null. My question is: what will happen if we call doFinal() with a 4 byte array to encrypt, and the buffer size is 8 bytes, how many bytes encoded data will we receive on the return?

update(): feed the data, again and again, enables you to encrypt long files, streams.
dofinal(): apply the requested padding scheme to the data, if requested and necessary, then encrypt. ECB and CBC mode requires padding but CTR mode doesn't. If NOPADDING has used some libraries may secretly pad, in others you have to handle the padding yourself.
When you call, dofinal() with 4-byte data, if NOPADDING is not set, it will be padded and then encrypted.
From Java Doc;
update(byte[] input)
Continues a multiple-part encryption or decryption operation (depending on how this cipher was initialized), processing another data part.
doFinal()
Finishes a multiple-part encryption or decryption operation, depending on how this cipher was initialized.

Related

AES encryption constant input and output size

I have a key for AES encryption and I'm trying to encrypt strings with constant length as well, does the resultant encrypted string will always have the same length?
That depends on what you mean by 'the same length'.
The same length as the original string: generally no; the original string will be padded to a multiple of the cipher block-length. Check padding modes for details.
The same length every time you encrypt: yes; as long as you stick to the same mode and padding the encrypted output will have the same length.
First of all, a block cipher requires a full block to encrypt, therefore AES requires 16-byte ( or 128-bit ) input to encrypt will output 16-byte ciphertext. This is always the case for block ciphers since they are Pseudo-Random Permutations (PRP) - they are always permutations we expect them to be PRP.
Block ciphers, like AES, are primitives and must be used with a proper mode of operation. Here we will talk only about some of them.
ECB mode is the default and insecure.
Padding: In the case of the message size is not a multiple of the 128, we apply padding. There are various paddings, however, the most common one is the PCKS#7 ( update of PCKS#5 that was for 64-bit block ciphers like DES). This padding append characters to the end so that the size is multiple of 128.
Therefore; the appended number of characters for ECB mode can be from 1 to 16 ( if the block size is already a multiple of 128) then a new block is added with 16 10 bytes.
CBC mode requires a random and unpredictable IV so that we can achieve probabilistic encryption. As in ECB, it requires padding.
Therefore; the appended number of characters for CBC mode can be from 1+16 to 32 since we need to add the IV to the ciphertext.
CTR mode requires Initial Value (IV) that can be random or deterministic. CTR mode converts a block cipher (PRP) into a stream cipher. The plaintext is x-ored with the ciphertext where the input was the IV and incremented for each encryption. There is no need for padding in CTR mode.
Therefore; the appended number of characters for CTR mode is (at most)16.
AAED: The above are archaic mode of operations and today we use Authenticated Encryption (with Associated Data) (AE/AEAD). Unlike the archaic modes, these modes can provide us not only confidentiality but also integrity and authentication.
The authentication part requires a tag (MAC tag) and this really depends on the scheme.
AES-GCM is the NIST-approved mode. AES-GCM's recommended IV size 12 since different size requires an additional process. It always produces a 16-byte tag, however, one can reduce the size of the tag if they want to, although not recommended.
At first one might consider that the size is incremented by 12-16, however, it is not. The GCM always used Associated Data (AD) and allows zeroAD and the size of the AD is always added. For details, see NIST GCM specification
This was the short story of the long list of how the mode of operations behaves in terms of input vs output length.
If you omit the IV size, it is possible with CTR mode.

How does an IV work and what would be the best way to store it?

I want to encrypt and decrypt strings. I'm using Nodejs crypto for this. I've read that when encrypting and decrypting it's highly recommended to use an IV. I want to store the encrypted data inside a MySQL database and decrypt it later when needed. I understand that I need the IV also for the decryption process. But what exactly is an IV and how should I store it? I read something about that an IV does not to be kept secret. Does this mean I can store it right next to the encrypted data it belongs to?
it's highly recommended to use an IV
No, it's required or you'll not get a fully secure ciphertext in most circumstances. At the very minimum, not supplying an IV for the same key and plaintext message will result in identical ciphertext, which will leak information to an adversary. In other words: encryption would be deterministic, and that's not a property that you want from a cipher. For CTR and GCM mode you may well leak all of the plaintext message though...
But what exactly is an IV ... ?
An IV just consists of binary bits. It's size and contents depend on the mode of operation (CBC/CTR/GCM). Generally it needs either to be a nonce or randomized.
CBC mode requires a randomized IV of 16 bytes; generally a cryptographically secure random number generator is used for that.
CTR mode commonly specifies both a nonce and the initial counter value within the IV of 16 bytes. So you already need to put the nonce in the left hand bytes (lowest index). This nonce may be randomized, but then it should be large enough (e.g. 12 bytes) to avoid the birthday problem.
GCM mode requires just a nonce of 12 bytes.
and how should I store it
Anyway you can store the bytes, as long as they can be retrieved or regenerated during decryption. If you need text you may need to encode it using base 64 or hexadecimals (this goes for the ciphertext as well, of course).
I read something about that an IV does not to be kept secret.
That's correct.
Does this mean I can store it right next to the encrypted data it belongs to?
Correct, quite often the IV is simply prefixed to the ciphertext; if you know the block cipher and mode of operation then the size is predetermined after all.

When deciphering with RC4, what does it mean to skip bytes?

I have the binary data that I need to decipher, the algorithm (RC4) and the key. However, to decipher the data, one instruction I got is that "the length of the key initially gets skipped" or that "len bytes are skipped initially".
What does this mean exactly? Does it mean that if my key is 10 bytes long, that I need to pass in the binary data without the first 10 bytes to the decipher and then concatenate the first 10 bytes with the deciphered bytes?
const decipher = crypto.createDecipheriv('RC4', 'mysuperkey', null);
const buffer = decipher.update(data.slice('mysuperkey'.length));
decipher.final();
This does not work, so I might not understand the instruction.
RC4 is insecure for the first bits, so often you are instructed to skip over some initial bytes of the key stream. The way a stream cipher works is that it creates a stream of pseudo random data that depends on the key. That stream is XOR'ed with the plaintext to create the ciphertext, and with the ciphertext to create the plaintext.
To skip a number of bytes of the key stream you can simply encrypt / decrypt some (zero valued) bytes and throw away the results. This goes both for encryption and decryption. If the API has a specific skip method then you should of course use that, but I don't think it is present in CryptoJS.

DES and ICryptoTransform

This method works fine in a program I've made. However I cannot really understand what is happening and where the encryption is actually performed. I read the related description from MSDN but not much information is given.
Can someone explain what is happening in general especially in line 8 and 9 please.
public byte[] Decrypt(byte[] input, byte[] key, byte[] iv)
{
DES des = new DESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.None;
des.Key = key;
ICryptoTransform ct = des.CreateDecryptor(key, iv);
byte[] result = ct.TransformFinalBlock(input, 0, input.Length);
return result;
}
If you want to understand what is going on, you should read about block cipher operations here:
http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29
In a nutshell, block ciphers chaining causes the input of one block operation to be fed into the next block operation. This obscures any block-level patterns in the ciphertext. Since there is a chaining structure, the last block gets an input from the second last block, and so on... until the second block gets an input from the first block. Now the first block needs to get an input from something, but there are no preceding blocks. So we use something called an Initialization Vector (iv) to start it off. This IV does not need to be secret like the key, but it does need to have a low probability of re-use (otherwise the attacker can use it to correlate the first blocks of all your ciphertexts). Typically random numbers are used, or sometimes increasing sequence numbers.
In regard to the specific call:
Your method works to decrypt a single block using DES. (Which is nowadays considered out of date and insecure, by the way, please consider using AES instead - the block cipher structures remain the same so all you need to do is swap the library). Anyway,
Since you're using a cipher in ECB mode, each block is decrypted independently with the same initialization vector, which is provided to your Decrypt method call. The call to CreateDecryptor initializes a decryption object using the provided secret key and initialization vector.
The actual decryption is performed using the call to TransformFinalBlock. The arguments are the input byte array, and then an offset and a length parameter (used for when you don't want to decrypt the entire byte array). In this case you do want to use the entire byte array so the starting offset is 0 and the size is the length of the whole byte array.
One thing you should probably add is to check that the input byte array is the correct block size for your cipher, otherwise it will throw an exception. In the case of DES, this is 64 bits. If you switch to AES as I recommended it will be 128 bits.

Audio, AES CBC and IVs

I'm currently working on a voip project and have a question about the implementation of AES-CBC mode. I know that for instant messaging based on text message communication, it's important to generate an IV for every message to avoid possible guess of the first block if this one is redundant during the communication.
But is it useful to do the same with audio data ? Since audio data is much more complex than clear text, i'm wondering if it would be wise to generate an IV for each audio chunk ( that would mean a lot of IVs per second, more than 40 ), or will this just slow everything down for nothing? Or just one IV generated at the start of the conversation should be enough?
Thanks in advance,
Nolhian
You do not need to generate new IVs each time.
For example, in SSH and TLS only one IV is used for a whole data session, and rekeying is needed only after some gbytes of data.
CBC requires a new IV for each message. However nobody said that you had to send a message in one go.
Consider SSL/TLS. The connection begins with a complex procedure (the "handshake") which results in a shared "master key" from which are derived symmetric encryption keys, MAC keys, and IVs. From that point and until the connection end (or new handshake), the complete data sent by the client to the server is, as far as CBC is concerned, one unique big message which uses, quite logically, a unique IV.
In more details, with CBC each block (of 16 bytes with AES) is first XORed with the previous encrypted block, then is itself encrypted. The IV is needed only for the very first block, since there is no previous block at that point. One way of seeing it is that each encrypted block is the IV for the encryption of what follows. When, as part of the SSL/TLS dialog, the client sends some data (a "record" in SSL speak), it remembers the last encrypted block of that record, to be used as IV for the next record.
In your case, I suppose that you have an audio stream to encrypt. You could handle it as SSL/TLS does, simply chopping the CBC stream between blocks. It has, however, a slight complication: usually, in VoIP protocols, some packets may be lost. If you receive a chunk of CBC-encrypted data and do not have the previous chunk, then you do not know the IV for that chunk (i.e. the last encrypted block of the previous chunk). You are then unable to properly decrypt the first block (16 bytes) of the chunk you receive. Whether recovery from that situation is easy or not depends on what data you are encrypting (in particular, with audio, what kind of compression algorithm you use). If that potential loss is a problem, then a workaround is to include the IV in each chunk: in CBC-speak, the last encrypted block of a chunk (in a packet) is repeated as first encrypted block in the next chunk (in the next packet).
Or, to state it briefly: you need an IV per chunk, but CBC generates these IV "naturally" because all the IV (except the very first) are blocks that you just encrypted.

Resources