This file doesn't document the code but tries to answer questions I was confronted with when writing the code. For a documentation of the code see the the 'README.txt' file. Before you read on please keep in mind: I am not a professional cryptographer and got only into this out of curiosity. Thus everything I write in the following should be taken with a grain of salt: it's the result of some reading I've done and I may have misunderstood a lot (or read misinformation). The same goes for the code you may have downloaded: while being written with the best intentions, it's by an amateur in this field and neither has been tested extensively nor vetted by real experts! 1) Basics ========= AES256 encryption is a block cipher, using a 256 bit (32 byte) wide key and encrypts a 128 bit (16 byte) wide message. If the message is longer the obvious way to handle this would seem to split up the message into 16 byte wide chunks and encrypt them one after another. That is what the ECB mode (Electronic Codebook) does. Unfortunately, this approach is very insecure! When you encrypt several blocks with the same key, blocks with identical content get encrypted into identical ciphertext. And that's something you definitely don't want. Why? There's a nice example in Wikipedia on the result, see https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation and scroll down to the picture of a penguin. which is a bitmap file. If encrypted that way the consequence is that a lot of the patterns in the original image are repeated and can still directly be seen in the encrypted version. If that doesn't convince you that this isn't the way to go I can't help it;-) For messages longer than the AES256 block length of 16 bytes some additional "obfuscation" is thus required. Two things are used for this: an "initialization vector" ("IV" for short) and a method of mixing in information from the previously encrypted block(s) into the encryption of the next one when encrypting with the same key. The IV "primes" the encryption process - and is then also needed for to decrypt it. When a different IV is used (but the same key) for encrypting the same plaintext it results in a completely different ciphertext. And that is important: you don't want an "attacker" to guess at repeating patterns in your message (which often exist), thus allowing him to make educated guesses at the plaintext and, in turn, the key you were using. Thus a new IV, never used before, has to be used for encrypting with the same key for each message, and it needs to be completely unpredictable (the exception seems to be OFB mode, where unpredictability is not required, but still a different IV for each message). You could use a table to keep track of which IVs you've already used (but which can be a bit hard to organize) or bet on your luck and use a randomly generated IV (with its 128 bits chances that you pick the same one again are low, in the order of 10^-38, i.e. much lower than winning the jackpot in the lottery). But keep in mind that the IV is not a secret! It's just something that avoids the same plaintext getting encrypted into the same ciphertext. What you and the recipient of your message must keep secret is the key, not the IV. It may feel a bit uncomfortable to send the IV in plain for everyone to see, but there's no way around that. The recipient of the message needs it for decryption, and he's (hopefully) the only other person beside you that also knows the key. So you have to pass it along with the message. Otherwise the IV would be kind of a second secret key which you would have to agree upon with the other side, and that not only once (as for the key) but for each new message! When you need some "initialization vector" for the first 16 bytes of your messages, then it should be obvious that you need something similar for the next block. Using the same IV again is no good idea, it's nearly as bad as using none at all. Instead, there are different schemes to create this "primer" for the encryption of the next block. This is where the different "block chaining modes" come in: some of the information from the encryption of the previous block is fed into the encryption of the next one. This can be (in the case of CBC and CFB mode) the encrypted block itself, or some, typically XOR-ed, combination from the data at different stages of the encryption process. This is then used as the new "IV" for the encryption of the next block. And only the person that knows the secret key can figure it out. "Block chaining" isn't specific to AES, it's also done for other kinds of block cipher. Please refer to the above cited Wikipedia article for an overview. Currently, the following "block chaining modes" are supported: a) Electronic Codebook (ECB) b) Cipher Block Chaining (CBC) c) Propagating Cipher Block Chaining (PCBC) d) Cipher Feedback 128 (CFB-128) (often just called CFB) e) Cipher Feedback 8 (CFB-8) f) Output Feedback (OFB) g) Counter (CTR) The CFB-128 and CFB-8 modes differ in the number of bits encrypted and decrypted when working on blocks of 16 bytes. CFB-128 works on the whole block at once, and only a single encryption or decryption step is used. CFB-8 encrypts and decrypts single bytes, so 16 steps are required, making it slower. (The bit-oriented CFB-1 mode is not supported since this package doesn't deal with single bits.) The advantage of working on less than a complete block is that error recovery is easier - CFB-8 can recover the remains of the message except the bytes that got lost, were inserted or got garbled in transmission. Of course, you probably don't want to know all those details, you ask "which of those modes am I supposed to use for secure encryption?" To be honest, not being a seasoned cryptographer I also have to rely on hear-say. What I have read though is that the modes recommended are CBC (Cipher Block Chaining) and CTR (Counter) mode. CBC is used per default unless you explicitly select a different one. 2) Padding ========== As said above AES works on 16 byte blocks. So what to do when a message has a length that isn't an integer multiple of 16? The answer is to add some additional bytes to fill up the last block. Of course, the recipient must be able to determine where the original message ends. Thus a mutually agreed upon on scheme for such padding has to be used. Unfortunately, there isn't a single, generally accepted method of how to pad a message. The most commonly used methods are: 1) PKCS5/PKCS7 ("Cryptographic Message Syntax Standard", RSA Laboratories, Version 1.5/2.0 from 1993/1999): Set all the unused bytes to the number of padding (unused) bytes. 2) ISO/IEC 7816-4: Set the first unused byte to 0x80 and all the following ones to 0. 3) ANSI X9.23: Fill all unused bytes with 0 except for the very last one which is set to the number of padding bytes. 4) ISO 10126: Fill all unused bytes with random bytes except the very last one, which is set to the number of padding bytes (this standard was withdrawn in 2007, probably because one can't immediately see from the padding bytes if the message was garbled). 5) Fill all unused bytes with 0 - this is useful with C strings but doesn't work reliably for binary data which may contain sets of 0 bytes at the end and thus is unsuitable for most purposes. The code uses method 2 (ISO/IEC 7816-4) per default since it is recommended by the NIST Special Publication 800-38A, 2001 Edition, "Recommendation for Block Cipher Modes of Operation". Alternatively one can select PKCS5/PKCS7 or ANSI X9.23 mode (or all unused bits set to 0) by calling 'set_padding_mode()' - or already set it in the constructors. What about the case that the message has a length that's divisible by 16? In that case a complete block, consisting of padding only, is appended to the message (unless explicitly disabled) - otherwise the recipient could not reliably determine the real length of the message. However note that in some modes not the plaintext itself is encrypted but only the IV (the plaintext is just XOR-ed with the result to form the ciphertext)! These modes are CFB-128, CFB-8, OFB and CTR and they don't need any padding (as the encrypted message is exactly as long as the clear text). For these chaining modes the selected the padding mode is ignored. 3) Transmitting the IV ====================== Since the recipient needs to know the IV that was used to encrypt the message and the IV isn't a secret, the simplest strategy is to send it first, before the encrypted message. This also allows the recipient to start decrypting immediately since he doesn't has to wait for the IV and store more than 16 bytes of the message at a time. 2018/01/03 Jens Thoms Törring