A symmetric encryption algorithm is a two-way encryption procedure that employs the same key for both encryption and decryption of the information. Theoretically, this seems straightforward as both the sender and receiver of the message should know the key, however in practice safely sharing a key is very hard to do.
Symmetric-key algorithms can fall into 2 categories. They are:
- Stream ciphers, where each byte is encrypted one at a time.
- Block ciphers, where data is encrypted in blocks. These blocks can be different sizes based on the algorithms being used. The Advanced Encryption Standard uses a block size of 128 bits.
Similarities in the .NET Libraries
The AES, DES, and Triple DES algorithms in .NET all share a common abstract base class, SymmetricAlgorithm, which gives them a lot of common functionality. Before we look at the individual algorithms and examples of their use, let’s look at some of the common properties associated with them that you will need to use. The rest of the class is documented on MSDN .
The very first property we will look at is the Mode property on the SymmetricAlgorithm object. Block cipher algorithms such as AES, DES, and Triple DES encrypt data in block units rather than in single bytes at a time. The most common block size is eight bytes. Block ciphers use the same encryption algorithm for each block. Because of this, a block of plaintext will always return the same ciphertext when encrypted with the same key and algorithm. Because this behavior can be used to crack a cipher, cipher modes are introduced that alter the encryption process based on feedback from earlier block encryptions.
The cipher block chaining (CBC) mode introduces feedback. Before each plaintext block is encrypted, it is combined with the ciphertext of the previous block with a bitwise exclusive OR operation. This ensures that, even if the plaintext contains many identical blocks, they will each encrypt to a different ciphertext block. The initialization vector (IV) is combined with the first plaintext block by a bitwise exclusive OR operation before the block is encrypted.
Ciphertext feedback (CFB) is a mode of operation for a block cipher. In contrast to the CBC mode, which encrypts a set number of bits of plaintext at a time, it is at times desirable to encrypt and transfer some plaintext values instantly, one at a time. Like CBC, CFB also makes use of an IV. CFB uses a block cipher as a component of a random number generator. In CFB mode, the previous ciphertext block is encrypted and the output is exclusively ORed with the current plaintext block to create the current ciphertext block. The exclusive OR operation conceals plaintext patterns. Plaintext cannot be directly worked on unless there is a retrieval of blocks from either the beginning or end of the ciphertext.
The ciphertext stealing (CTS) mode handles any length of plaintext and produces ciphertext whose length matches the plaintext length. This mode behaves like the CBC mode for all but the last two blocks of the plaintext.
The electronic codebook (ECB) mode encrypts each block individually. Any blocks that are identical and in the same message, or that are in a different message encrypted with the same key, will be transformed into identical ciphertext blocks. The disadvantage of ECB mode is that identical plaintext blocks are encrypted to identical ciphertext blocks (thus, it does not hide data patterns well). In some senses, it doesn’t provide message confidentiality at all and so it is not recommended for cryptographic protocols.
The output feedback (OFB) mode processes small increments of plaintext into ciphertext instead of processing an entire block at a time. This mode is similar to CFB, but it differs in the way the shift register is filled. If a bit in the ciphertext is mangled, the corresponding bit of plaintext will be mangled. However, if there are extra or missing bits from the ciphertext, the plaintext will be mangled from that point on. The default mode in .NET for AES, DES, and Triple DES is CBC mode, and unless you have a good need to change that default mode, you should just go with the default.
Padding specifies what padding to apply when the message block being encrypted is shorter than the full number of bytes needed for a cryptographic operation.
- ANSIX923 – The ANSIX923 padding string consists of a sequence of bytes filled with zeros before the length.
- ISO10126 – The ISO10126 padding string consists of random data before the length.
- None – No padding is done.
- PKCS7 – The PKCS #7 padding string consists of a sequence of bytes, each of which is equal to the total number of padding bytes added.
- Zeros – The padding string consists of bytes set to zero.
The default padding in .NET for AES, DES, and Triple DES is PKCS7 mode, and unless you have a good need to change it, you should just go with the default.
The Key property is a byte array that is used to store the encryption key before to running encrypt and decrypt operations. The information in this property can literally be anything, but you should make sure you generate a safe key. There are two ways you can do this. You can use the RNGCryptoServiceProvider object and generate a byte array to the desired key length, or you can call the GenerateKey() method. Either way is fine.
Initialization Vector (IV)
The initialization vector (IV) property is a byte array that is used to store an IV. An IV is an arbitrary number that can be utilized along with a secret key for information encryption. This number, also called a nonce, is used only one time in any session.
The use of an IV prevents repetition in data encryption, which makes it more difficult for a hacker who is using a dictionary attack to find patterns to break a cipher. For example, a sequence might appear twice or more within the body of a message. If there are repeated sequences in encrypted data, an attacker could assume that the corresponding sequences in the plaintext message were also identical. The IV stops the appearance of identical character sequences within the ciphertext.