Handling AES encryption using CTR mode (storing vi) - encryption

I was trying to come up with AES encryption scheme for my project. Basically I want the user to crypt data using just a 32 byte key to decrypt a file of crypted data, since remembering and storing vi for every block seems very cumbersome. I know of many encryption programs that use just a key for encryption and nothing else. How do i go about this problem?
My current scheme looks something like this:
Block:
16 bytes vi,
up to 1 048 576 bytes of data (1MB)
Encryption:
Input 32 byte key
First vi is randomly generated 16
bytes that get encrypted with AES ECB (initial key)
1MB of data is encrypted using CTR (initial key, the block vi)
Any further block follows the same logic
Decryption:
Input 32 byte key
Decrypt first 16 bytes using ECB
Decrypt the first block of data using CTR (initial key, the block vi)
Any further block follows the same logic
Is this good enough security wise? I think it should work since vi for every block is random, and since vi itself is encrypted using ECB it works pretty much like one time pad, correct?

Related

How I can encrypt data with 32 bits length using AES algorithm?

I have a version of AES algorithm with 128bits in plaintext, now i want to change this version to 32bits in plaintext . How can i do this, please ?
That's part of my code when i send data to core AES, i send 128bits to encrypt and i check if the result is true.
apb_write(x"e2bec16b",AES_CMD_ADDR_DATAIN_0);
apb_write(x"969f402e",AES_CMD_ADDR_DATAIN_1);
apb_write(x"117e3de9",AES_CMD_ADDR_DATAIN_2);
apb_write(x"2a179373",AES_CMD_ADDR_DATAIN_3);
apb_write(x"80000005",AES_CMD_ADDR_CONTROL); --confige AES with mode (CBC)
apb_write(x"acab4976",AES_CMD_ADDR_DATAOUT_0);
apb_write(x"46b21981",AES_CMD_ADDR_DATAOUT_1);
apb_write(x"9b8ee9ce",AES_CMD_ADDR_DATAOUT_2);
apb_write(x"7d19e912",AES_CMD_ADDR_DATAOUT_3);
The question : how i can send just 32bits and check , after, send 32bits and check ....?
how i can do this ?
AES is as far as I know only defined for blocks of 128 bits.
If you want to encrypt blocks of 32 bits, you'd need to pad your plain text (with for example 0's) until you reach 128 bits. Then, if you want to decrypt it, just decrypt it normally and after the decryption chop off the last (or first, depending which side you padded) 96 (128 - 32) bits.

Random access encrypted file

I'm implementing a web based file storage service (C#). The files will be encrypted when stored on the server, but the challenge is how to implement the decryption functionality.
The files can be of any size, from a few KB to several GB. The data transfer is done in chunks, so that the users download the data from say offset 50000, 75000 etc. This works fine for unencrypted files, but if encryption is used the entire file has to be decrypted before each chunk is read from the offset.
So, I am looking at how to solve this. My research so far shows that ECB and CBC can be used. ECB is the most basic (and most insecure), with each block encrypted separately. The way ECB works is pretty much what I am looking for, but security is a concern. CBC is similar, but you need the previous block decrypted before decrypting the current block. This is ok as long as the file is read from beginning to end, and you keep the data as you decrypt it on the server, but at the end of the day its not much better than decrypting the entire file server side before transferring.
Does anyone know of any other alternatives I should consider? I have no code at this point, because I am still only doing theoretical research.
Do not use ECB (Electronic Code Book). Any patterns in your plaintext will appear as patterns in the ciphertext. CBC (Cipher Block Chaining) has random read access (the calling code knows the key and the IV is the previous block's result) but writing a block requires rewriting all following blocks.
A better mode is Counter (CTR). In effect, each block uses the same key and the IV for each block is the sum of offset of that block from a defined start and an initial IV. For example, the IV for block n is IV + n. CTR mode is described in detail on page 15 in NIST SP800-38a. Guidance on key and IV derivation can be found in NIST SP800-108.
There are a few other similar modes such as (Galois Counter Mode) GCM.

Emulate 3DES EDE using only DES

My device doesn't support full 3DES (EDE). How can I emulate one using standard DES? Encryption mode is CBC.
You start by picking three independent DES keys which are not related to each other in any way.
You will want to put DES into ECB mode, not CBC mode. You also need to ensure that each encryption and decryption operation is done only on 64-bit blocks and nothing more or less. Padding schemes and the likes will cause a vulnerability in the implementation and will lead to the discovery of the block content via brute force faster than a brute force against each key.
Using the first key, encrypt your plaintext. Using the second key, decrypt that value. Using the third key, encrypt the value for your full block. It looks like this:
Encrypt(k3, Decrypt(k2, Encrypt(k1, plaintext)))
Decryption is the other way around and looks like this:
Decrypt(k1, Encrypt(k2, Decrypt(k3, ciphertext)))
When you encrypt your blocks with 3DES you then need to apply your mode of operation like CBC or CTR and apply padding if needed.
Be careful.
Block mode encryption
What you do is that you split the key of size 128 bit (16 byte) or 168 bit (24 byte) in two or three pieces respectively. So for a 16 byte key K you would have two keys Ka and Kb, and for a 24 byte key you would have Ka, Kb and Kc. DES ABC keys have an effective strength of about 112 bits, DES ABA keys have an effective strength of about 80 bits.
To encrypt a single block of 8 bytes (the block size of both DES and 3DES) you would perform the following cryptographic operation: Cn = E(Ka, D(Kb, E(Kc, Mn))) where Mn is the n'th block of the plain text message and Cn the n'th block of the cipher text. If you don't have a Kc then you may use Ka (DES ABC key vs DES ABA key).
For this you need a single block DES encrypt, which is identical to a single block encrypt in ECB mode, or a single block encrypt with CBC and an IV consisting of 8 bytes valued 00h.
CBC
So that's the block encryption sorted, now you need some kind of encryption mode and padding mode. I'll explain CBC mode encryption here, ECB should not be used for encryption non-random data.
With CBC mode encryption you XOR a vector to the plain text. The vector is normally just the output of the last DESede encrypted block. As you don't have any preceding cipher text, you need to create the first vector yourself using random data. This vector is called the initialization vector or IV. See wikipedia for a clear picture.
Padding
Block cipher modes only allow full blocks of plain text to be encrypted. So you would need some kind of padding scheme. Although there are many padding modes, PKCS#5 padding is used most of the time. You should pad the plain text like this: pad with bytes valued 0Xh, where X is the number of padding bytes required to create a full block. X should be between 1 and 8: in other words, PKCS#5 padding is always used; this makes it possible to distinquish the padding bytes from the plain text.
If you use padding in an online protocol then you need to protect against padding oracle attacks. In this case it is highly recommended to use some form of integrity checks, e.g. by adding a HMAC over the cipher text using a separate key.
3DES is just DES used three times on the plaintext:
ciphertext = E_K3(D_K2(E_K1(plaintext)))
plaintext = D_K1(E_K2(D_K3(ciphertext)))
E_Kn = Encryption with Key number n.
D_Kn = Decryption with Key number n.
So you can easily "emulate" 3DES with just DES.
In CBC mode you'll need an IV to start with and then XOR the next plaintext block with the previous ciphertext block. If your device doesn't support CBC then this too is easily "emulated".

Key salt and initial value AES

I am creating an encryption scheme with AES in cbc mode with a 256-bit key. Before I learned about CBC mode and initial values, I was planning on creating a 32-bit salt for each act of encryption and storing the salt. The password/entered key would then be padded with this salt up to 32 bits.
ie. if the pass/key entered was "tree," instead of padding it with 28 0s, it would be padded with the first 28 chars of this salt.
However, this was before I learned of the iv, also called a salt in some places. The question for me has now arisen as to whether or not this earlier method of salting has become redundant in principle with the IV. This would be to assume that the salt and the iv would be stored with the cipher text and so a theoretical brute force attack would not be deterred any.
Storing this key and using it rather than 0s is a step that involves some effort, so it is worth asking I think whether or not it is a practically useless measure. It is not as though there could be made, with current knowledge, any brute-force decryption tables for AES, and even a 16 bit salt pains the creation of md5 tables.
Thanks,
Elijah
It's good that you know CBC, as it is certainly better than using ECB mode encryption (although even better modes such as the authenticated modes GCM and EAX exist as well).
I think there are several things that you should know about, so I'll explain them here.
Keys and passwords are not the same. Normally you create a key used for symmetric encryption out of a password using a key derivation function. The most common one discussed here is PBKDF2 (password based key derivation function #2), which is used for PBE (password based encryption). This is defined in the latest, open PKCS#5 standard by RSA labs. Before entering the password need to check if the password is correctly translated into bytes (character encoding).
The salt is used as another input of the key derivation function. It is used to prevent brute force attacks using "rainbow tables" where keys are pre-computed for specific passwords. Because of the salt, the attacker cannot use pre-computed values, as he cannot generate one for each salt. The salt should normally be 8 bytes (64 bits) or longer; using a 128 bit salt would give you optimum security. The salt also ensures that identical passwords (of different users) do not derive the same key.
The output of the key derivation function is a secret of dkLen bytes, where dkLen is the length of the key to generate, in bytes. As an AES key does not contain anything other than these bytes, the AES key will be identical to the generated secret. dkLen should be 16, 24 or 32 bytes for the key lengths of AES: 128, 192 or 256 bits.
OK, so now you finally have an AES key to use. However, if you simply encrypt each plain text block with this key, you will get identical result if the plain text blocks are identical. CBC mode gets around this by XOR'ing the next plain text block with the last encrypted block before doing the encryption. That last encrypted block is the "vector". This does not work for the first block, because there is no last encrypted block. This is why you need to specify the first vector: the "initialization vector" or IV.
The block size of AES is 16 bytes independent of the key size. So the vectors, including the initialization vector, need to be 16 bytes as well. Now, if you only use the key to encrypt e.g. a single file, then the IV could simply contain 16 bytes with the value 00h.
This does not work for multiple files, because if the files contain the same text, you will be able to detect that the first part of the encrypted file is identical. This is why you need to specify a different IV for each encryption you perform with the key. It does not matter what it contains, as long as it is unique, 16 bytes and known to the application performing the decryption.
[EDIT 6 years later] The above part is not entirely correct: for CBC the IV needs to be unpredictable to an attacker, it doesn't just need to be unique. So for instance a counter cannot be used.
Now there is one trick that might allow you to use all zero's for the IV all the time: for each plain text you encrypt using AES-CBC, you could calculate a key using the same password but a different salt. In that case, you will only use the resulting key for a single piece of information. This might be a good idea if you cannot provide an IV for a library implementing password based encryption.
[EDIT] Another commonly used trick is to use additional output of PBKDF2 to derive the IV. This way the official recommendation that the IV for CBC should not be predicted by an adversary is fulfilled. You should however make sure that you do not ask for more output of the PBKDF2 function than that the underlying hash function can deliver. PBKDF2 has weaknesses that would enable an adversary to gain an advantage in such a situation. So do not ask for more than 256 bits if SHA-256 is used as hash function for PBKDF2. Note that SHA-1 is the common default for PBKDF2 so that only allows for a single 128 bit AES key.
IV's and salts are completely separate terms, although often confused. In your question, you also confuse bits and bytes, key size and block size and rainbow tables with MD5 tables (nobody said crypto is easy). One thing is certain: in cryptography it pays to be as secure as possible; redundant security is generally not a problem, unless you really (really) cannot afford the extra resources.
When you understand how this all works, I would seriously you to find a library that performs PBE encryption. You might just need to feed this the password, salt, plain data and - if separately configured- the IV.
[Edit] You should probably look for a library that uses Argon2 by now. PBKDF2 is still considered secure, but it does give unfair advantage to an attacker in some cases, letting the attacker perform fewer calculations than the regular user of the function. That's not a good property for a PBKDF / password hash.
If you are talking about AES-CBC then it is an Initialisation Vector (IV), not Salt. It is common practice to send the IV in clear as the first block of the encyphered message. The IV does not need to be kept secret. It should however be changed with every message - a constant IV means that effectively your first block is encrypted in ECB mode, which is not properly secure.

AES init vector

Do I have provide AES key + IV for someone to be able to decrypt encrypted data?
Does that increase key length from 128 bit to 256 bits?
Yes, both the key and the IV are needed to decrypt something. Generally, the key should be exchanged using a secure channel or key exchange mechanism. The IV can be transmitted along with the encrypted data in plain text. An IV should ideally be used only once. The main motivation behind using a changing IV is that encrypting the same thing twice should not result in the same ciphertext both times, because this can allow an attacker to draw conclusions about the data encrypted.

Resources