These are the type of ciphers that use the same key both for decryption and encryption.
The simplest example of a symmetric cipher is the XOR operator:
plain text: 1101 key: 0101 cypher text: 1101 XOR 0101 == 1000 back to plaintext: 1000 XOR 0101 == 1101
It encrypts one word at the time. (word could have any size, 1 bit, 1 byte, 4 byte). The earlies example of this type of cipher is the Caesar cipher also known as the shift cipher. Every letter of the message is shifted X positions to the left:
Shift 3 to the left: Plaintext: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG Ciphertext: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD
In modern stream ciphers, we use the key as a seed for a keystream generator. This generates a key large enough to encrypt all the plaintext.
The keystream is generated all at once, based on the original seed.
The fist keystream is generated based on the seed. Subsequent keystream use a combination of the seed and the cipher text encrypted in the previous round.
RC4: Probably the most famous stream cipher. Designed by Ron Rivest in 1987. The use of RC4 is prohibited on TLS as of Feb 2015 (rfc7465)
A5/1: Used for encryption over the air on GSM. Created in France in 1987 (A weaker export version named A5/2 exists). Both can be break almost on real time.
Salsa20 and the closely related ChaCha are stream ciphers developed by Daniel J. Bernstein. Salsa20, the original cipher, was designed in 2005, then later submitted to eSTREAM by Bernstein. ChaCha is a modification of Salsa20 published in 2008. It uses a new round function that increases diffusion and increases performance on some architectures
Let's use a 128-Bit key to encrypt a text message using RC4.
We will provide a key encoded in hexadecimal numbers (32 characters or 16 octets)
# Create a random key of 16 hexadecimal characters osboxes@osboxes:~$ xxd -l 16 -p /dev/random ef604a02f3c0c5402b8bf2570a3ad896 # Cipher our 10 bytes of text: osboxes@osboxes:~$ echo -n "first test" | openssl rc4 -e -K ef604a02f3c0c5402b8bf2570a3ad896 | xxd 00000000: 7007 c29d 7aab dfa4 ca0c p...z..... # Output on base64 (to use as input to decrypt) osboxes@osboxes:~$ echo -n "first test" | openssl rc4 -e -K ef604a02f3c0c5402b8bf2570a3ad896 | base64 -w0 cAfCnXqr36TKDA== # Decrypt our text osboxes@osboxes:~$ echo -n "cAfCnXqr36TKDA==" | base64 -d | openssl rc4 -d -K ef604a02f3c0c5402b8bf2570a3ad896 first test
The input is fixed in size, a block of X number of bits, usually 128 bits. If the block is to small, we use padding.
In block ciphers, because the input size is known and fixed, the encryption is done by a 1:1 mapping of input and output blocks.
With 2 bit blocks 00 -> 01 01 -> 11 10 -> 00 11 -> 10
In order for this to work, we need to use secure permutations:
Dates back to 1972, created by an open request made by the US Government. The initial design (named lucifer) suggested a block of 64 bit and a 128 bit key. Upon review, the NSA (known by a different name back then) recommended a change of key size to 56 bit (plus 8 bits of parity).
Practical attacks for this algorithm became available in 2005. It shouldn't be used with TLS 1.3 - Replaced by AES and 3DES. The soviets created an equivalent algorithm during the cold war named GOST with a 265 bit key and blocks of 128 bit. The Japanese equivalent, CAMELLIA, uses a block of 128 bit and keys of size 128/192/156 bits
DES parity bit: DES was developed in a time where network/hardware errors were a common thing, and we didn't have layers to verify the integrity of the data. For this reason, the key includes 8 bits of parity. On every byte inside the key, 7 bits are part of the key, and the last one is used for parity (value is 0 if the previous 7 are even, and 1 is they're odd).
osboxes@osboxes:~$ echo "hi there" | openssl enc -des-cbc -e -K 0000000001010101 -iv 0 2>/dev/null | xxd 00000000: 2157 8b0f 79af 9d24 73dc dc88 59e4 2ed8 !W..y..$s...Y... osboxes@osboxes:~$ echo "hi there" | openssl enc -des-cbc -e -K 0000000000000000 -iv 0 2>/dev/null | xxd 00000000: 2157 8b0f 79af 9d24 73dc dc88 59e4 2ed8 !W..y..$s...Y...
Padding The padding used by DES is also used by other algorithms. It's defined by the PKCS (Public Key Cryptography Standards). If only one byte of padding is required, we include 0x01, if two bytes are required, 0x02 .. and so on. If no padding is required, we include an additional block of 0x08.
Similar to DES, but it uses 3 keys instead of one. It encrypts the plaintext with K1, then decrypts with K2, and encrypt again with K3. It was designed this way to keep backwards compatibility with DES - Using the same key thrice is equivalent to encrypting with DES. Reduces the chances of bruteforce attack with 3 keys.
Came out of a competition in the late 90s. The algorithm needed to support a block size of 128 bit and keys of size of 128/192/256. The jury selected an algorithm submitted by two Belgians (Rijmen/Daemen) named Rijndael. No known cryptanalytical attacks. Types of mode of operation:
Electronic codebook - Very fast encryption, can be done in multiple blocks in parallel.
This method is deterministic, the same patterns in the input are kept in the output.
It can be executed in parallel, because there is no relation between the blocks.
ECB mode is NOT recommended to use in practice, because the pattern is never changed between input and output.
For example, a picture encrypted with ECB mode, will look very similar after encryption, because it has the same patterns.
In this example, the input contains 32 characters of 8bit for a total of 256 bits, or 2 128 bit blocks.
osboxes@osboxes:~$ echo -n aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | openssl enc -e -aes-128-ecb -K 01234567890123456789012345678901 | xxd 00000000: 1e99 4d3e a034 fbc9 ebeb 9120 4d1a 5a00 ..M>.4..... M.Z. 00000010: 1e99 4d3e a034 fbc9 ebeb 9120 4d1a 5a00 ..M>.4..... M.Z. 00000020: 493f 1454 b089 8f0f 3be6 0fc9 3c5c 915e I?.T....;...<\.^
The encrypted output includes the same block twice, followed by a last block of padding.
NON-ECB There are many different NON-ECB modes of operations, but in essence, they all rely on using an IV initialization vector, or a nonce (number once) to generate a non-deterministic output on the blocks.
Cipher block chaining: The IV is used to XOR against the first block of plain text, and then the output is used as the first input block. The cipher block that comes out from the first operation is then used as the IV of the second block, hence the "chaining" in the name. With this mode, decryption can be done in parallel. The IV makes sure that the encryption is probabilistic, not deterministic.
Counter mode: On this mode, the IV is split between a fix portion, and a counter portion. The counter increases by 1 for every block we try to cipher. The counter is encrypted with the key (block encryption), and the output is XOR with the plain text (stream cipher). We use a block cipher, to generate the keystream cipher. It's a very fast mode of operation, because both encryption and decryption can be performed in parallel. Counter mode is knonw as ctr, or gcm Galois Counter Mode.
The PKCS defines functions used to convert easy to remember passwords into key/IV for encryption. Openssl accepts a password as the input and then uses its own implementation of PBKDF (Password-Based Key Derivation Function) to generate the key.
osboxes@osboxes:~$ openssl enc -des-cbc -k hello -e -pbkdf2 -P salt=6EE35304A6FF3205 key=2AE6EC3DC05EB15B iv =E9DA4C2943A27462
The function takes as input: hash type, iterations, output size, salt, password
A large number of iteration reduces the chance of a brute force attack.