user1256821
user1256821

Reputation: 1188

Encoding file with AES

I am writing a server in C and I would like to encode file with aes.

As I know the encoding block size should be equal to the AES key length, so I need to complement last block with zeros to the required size. The problem is in decoding: how to distinguish the file contents and the complementing zeros? Well, I planned to use Base64 encoding for that purpose, but isn't it too slow for large files? May be I should send file size before sending encoded blocks?

Upvotes: 1

Views: 958

Answers (3)

ouah
ouah

Reputation: 145899

See this page about padding schemes:

http://en.wikipedia.org/wiki/Padding_(cryptography)

For example for CBC mode:

One method is to fill out the last block with a 1-bit followed by zero bits. If the input happens to fill up an entire block, a “dummy block” is added to accommodate the padding; otherwise, the end of the input plaintext might be misinterpreted as padding. Another method is to append n bytes with value (n−1) to the end of the plaintext to fill out a complete block. If the message already exactly fills a block, then for the same reasons as before, a full block of padding block is added. This means the padding is either one byte of 0, or two bytes of 1 etc.

If you use CTR mode no padding is even required as the cipher text is the same size as the plain text.

As noted by @maybewecouldstealavan a popular padding scheme is PKCS #5 from RSA Laboratories. This is the padding scheme used by OpenSSL program for the CBC mode.

All the block ciphers normally use PKCS#5 padding also known as standard block padding: this allows a rudimentary integrity or password check to be performed.

http://www.openssl.org/docs/apps/enc.html

Upvotes: 0

maybeWeCouldStealAVan
maybeWeCouldStealAVan

Reputation: 15610

A common scheme is PKCS#5 padding. Basically, fill the padding (of the plaintext) with bytes equal to the padding length. Then, after decryption, look at the last byte to see how many to drop. Confirming that the dropped bytes are the same provides a quick sanity check. Some examples, in hex:

[AABBCCDD EEFF0011 22334455 667788--] -> [AABBCCDD EEFF0011 22334455 66778801]
[AABBCCDD EEFF0011 22334455 66------] -> [AABBCCDD EEFF0011 22334455 66030303]
[AABBCCDD EEFF0011 22334455 66778899] -> [AABBCCDD EEFF0011 22334455 66778899][10101010 10101010 10101010 10101010]
//the last byte must be padding, even if that requires an extra block

Side note: If you're implementing the encryption yourself, read up on modes of operation as well. If you aren't, then whatever library you're using should be able to handle the padding.

Upvotes: 3

Sniggerfardimungus
Sniggerfardimungus

Reputation: 11782

It's not a good idea to Base64 encode your file and then AES-encrypt. Doing so reduces the number of possible blocks from 2^64 to 2^48 by setting the high 2 bits of every byte of cyphertext to a known value.

I'm not sure it's the "best" or the "normal" way to do it, but I've generally slapped a couple extra blocks on to the beginning or the end of my cyphertext which will decrypt to metadata about the file - size, filename, content-type, etc. Yes, these blocks have very little entropy, but it's far better to allow one or two blocks with a crib than to have every byte contain one.

For example, if you had a file that was 10 bytes long, you'd have one full block of cyphertext, a block that contained two useful bytes followed by 6 bytes of padding. The last block would contain your metadata. (Actually, the metadata block could go at the beginning or the end. Take your pick.)

Upvotes: 2

Related Questions