[Cryptography 2] Understand Symmetric Encryption - -- Symmetric Encryption by DES, 3DES, AES, Goang

Symmetric Encryption

Symmetric encryption: Refers to encryption using the same key when encrypting and decoding

1. Coding

Modern passwords are all based on computers, because modern passwords handle a very large amount of data, and the cryptographic algorithms are very complex, so encryption and decryption operations cannot be completed without the help of computers.

The object of computer operation is not text, but a sequence of bits arranged by 0 and 1. Whether it's text, images, sounds, videos or programs, bits are represented in a sequence of bits on a computer. A program that performs an encryption operation is to convert a sequence of bits representing plain text to a sequence of bits representing ciphertext.

The operation of mapping something in the real world to a sequence of bits is called encoding.

2,DES

2.1. What's DES

**DES (Data Encryption Standard)** is a symmetric password (FIPS46.3) used in the Federal Information Processing Standard (FIPS) of the United States in 1977. DES has been widely used by governments and banks in the United States and other countries. However, with the progress of computers, DES can now be cracked by violence, the intensity is not as strong as it used to be.

RSA has held a DES Challenge competition. We can take a look at the results officially announced by RSA:

  • DES Challenge1 in 1997 used 96 days to decipher keys
  • DES ChallengeIl-I in 1998 used 41 days to decipher keys
  • DES Challenge II-2 in 1998 took 56 hours to decipher the key
  • In 1999, DES ChallengeIll used only 22 hours and 15 minutes to decipher keys

Since DES ciphertext can be deciphered in a short period of time, we should not use DES now except to decrypt the previous ciphertext.

2.2, Encryption and Decryption

DES is a symmetric cryptographic algorithm that encrypts 64 bits of plain text into 64 bits of cipher, and its key length is 56 bits. Although the DES key length is 64 bits in specifications, it is essentially 56 bits because a bit is set for error checking every 7 bits.

DES is encrypted in 64-bit plain text (bit sequence) as a unit, which is called grouping. Generally speaking, the cipher algorithm that processes in groups is called block cipher, and DES is one of the block ciphers.

DES can only encrypt 64 bits of data at a time. If the plain text to be encrypted is longer, DES encryption needs to be iterated (iterated), and the exact way of iteration is called mode.

Key length: (56bit + 8bit)/8 = 8byte 12345678

2.3. Encryption and Decryption of DES - Legend

2.4, DES in go code implementation

package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/base64"
	"fmt"
)

func main() {
	// encryption
	key := []byte("11111111")
	result := DesEncrypt_CBC([]byte("yesyes hello world"), key)
	fmt.Println(base64.StdEncoding.EncodeToString(result))
	// Decrypt
	result = DesDecrypt_CBC(result, key)
	fmt.Println("Data after decryption: ", string(result))
}

// DesEncrypt_ CBC SRC ->Clear Text to Encrypt
// Key - > key, size: 8byte
func DesEncrypt_CBC(src, key []byte) []byte {
	// 1. Create and return a cipher using the DES algorithm. Block interface
	block, err := des.NewCipher(key)
	// 2. Determine if the creation was successful
	if err != nil {
		panic(err)
	}
	// 3. Fill in the last clear text group
	src = PKCS5Padding(src, block.BlockSize())
	// 4. Create a BlockMode l interface with DES encryption at the bottom that groups passwords into linked modes
	//    The length of parameter iv must be equal to the block size of b
	tmp := []byte("helloAAA")
	blackMode := cipher.NewCBCEncrypter(block, tmp)
	// 5. Encrypt contiguous data blocks
	dst := make([]byte, len(src))
	blackMode.CryptBlocks(dst, src)

	fmt.Println("Encrypted data: ", dst)

	// 6. Return encrypted data
	return dst
}

// DesDecrypt_ CBC SRC ->Password to Decrypt
// Key ->key, same size as encryption key: 8byte
func DesDecrypt_CBC(src, key []byte) []byte {
	// 1. Create and return a cipher using the DES algorithm. Block interface
	block, err := des.NewCipher(key)
	// 2. Determine if the creation was successful
	if err != nil {
		panic(err)
	}
	// 3. Create a BlockMode interface that uses DES decryption at the bottom and groups passwords in linked mode
	tmp := []byte("helloAAA")
	blockMode := cipher.NewCBCDecrypter(block, tmp)
	// 4. Decrypt data
	dst := src
	blockMode.CryptBlocks(src, dst)
	// 5. Remove the last set of populated data
	dst = PKCS5UnPadding(dst)

	// 6. Return results
	return dst
}

// PKCS5Padding is populated using pks5
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	// 1. Calculate how many bytes are missing from the last group
	padding := blockSize - (len(ciphertext) % blockSize)
	// 2. Create a slice of padding size with a value of padding per byte
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	// 3. Add padText to the back of the original data to complete the missing bytes in the last group
	newText := append(ciphertext, padText...)
	return newText
}

// PKCS5UnPadding Deletes Tail Data Filled by pks5
func PKCS5UnPadding(origData []byte) []byte {
	// 1. Calculate the total length of the data
	length := len(origData)
	// 2. Number of times to get a fill based on the byte value of the fill
	number := int(origData[length-1])
	// 3. Remove the number bytes filled with the tail
	return origData[:(length - number)]
}

3. Triple DES

The encryption and decryption mechanism of the triple DES is shown in the figure:

Add->Solution->Add->for des compatibility

3des key length 24 bytes = 1234567a 1234567b 1234567a

Clear text is processed three times by DES to become the last ciphertext. Since the length of the DES key is essentially 56 bits, the key length of the triple DES is 56 × 3=168 bits plus flag bit 8x3 for error detection, a total of 192 bits.

From the figure above, we can see that triple DES is not a three-time DES encryption (encryption ->encryption ->encryption), but an encryption ->decryption ->encryption process. It's incredible to encrypt and decrypt in an encryption algorithm. In fact, this method was designed by IBM to make the triple DES compatible with ordinary DES.

When all keys in a triple DES are the same, the triple DES is equivalent to the ordinary DES. This is because after the first two steps of encryption -> decryption, you get the original plain text. Therefore, previously encrypted DES ciphertext can be decrypted in this way using a triple DES. That is, triple DES is downward compatible with DES.

If key 1 and key 3 use the same key, and key 2 uses a different key (that is, only two DES keys), this triple DES is called DES-EDE2. EDE represents the process of Encryption --> Decryption --> Encryption.

The triple DES with key 1, key 2, and key 3 all using different bit sequences is called DES-EDE3.

Although the triple DES is currently used by banks and other institutions, its processing speed is not high, and some security issues are gradually emerging.

3.1 Triple DES Implementation in go

package main

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/base64"
	"fmt"
)

func main() {
	// encryption
	key := []byte("111111112222222233333333")
	result := TripleDESEncrypt([]byte("yesyes hello world"), key)
	fmt.Println(base64.StdEncoding.EncodeToString(result))
	// Decrypt
	result = TripleDESDecrypt(result, key)
	fmt.Println("Data after decryption: ", string(result))
}

// TripleDESEncrypt 3DES Encryption
func TripleDESEncrypt(src, key []byte) []byte {
	// 1. Create and return a cipher using the 3DES algorithm. Block interface
	block, err := des.NewTripleDESCipher(key)
	if err != nil {
		panic(err)
	}
	// 2. Fill in the last set of plaintext
	src = PKCS5Padding(src, block.BlockSize())
	// 3. Create a BlockMode model with password grouping as link mode and underlying 3D ES encryption
	blockMode := cipher.NewCBCEncrypter(block, key[:8])
	// 4. Encrypt data
	dst := src
	blockMode.CryptBlocks(dst, src)
	return dst
}

// TripleDESDecrypt 3DES Decryption
func TripleDESDecrypt(src, key []byte) []byte {
	// 1. Creating Block Interface Objects for 3DES Algorithms
	block, err := des.NewTripleDESCipher(key)
	if err != nil {
		panic(err)
	}
	// 2. Create a BlockMode model with password grouping in link mode and underlying decryption using 3DES
	blockMode := cipher.NewCBCDecrypter(block, key[:8])
	// 3. Decryption
	dst := src
	blockMode.CryptBlocks(dst, src)
	// 4. Remove trailing data
	dst = PKCS5UnPadding(dst)
	return dst
}

// PKCS5Padding is populated using pks5
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	// 1. Calculate how many bytes are missing from the last group
	padding := blockSize - (len(ciphertext) % blockSize)
	// 2. Create a slice of padding size with a value of padding per byte
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	// 3. Add padText to the back of the original data to complete the missing bytes in the last group
	newText := append(ciphertext, padText...)
	return newText
}

// PKCS5UnPadding Deletes Tail Data Filled by pks5
func PKCS5UnPadding(origData []byte) []byte {
	// 1. Calculate the total length of the data
	length := len(origData)
	// 2. Number of times to get a fill based on the byte value of the fill
	number := int(origData[length-1])
	// 3. Remove the number bytes filled with the tail
	return origData[:(length - number)]
}

4,AES

AES (Advanced Encryption Standard) is a symmetric cryptographic algorithm that replaces its predecessor standard (DES) and becomes a new standard. Enterprises and cryptographers around the world submitted several symmetric cryptographic algorithms as candidates for AES, from which a symmetric cryptographic algorithm named Rijndael was selected in 2000 and identified as AES.

Rijndael is a grouped cipher algorithm juiced by Belgian cryptographers Joan Daemen and Vincent Rijmen, and will be supported by more and more cryptographic software in the future.

Rijndael's grouping length is 128 bits, and the key length can be selected from 128 to 256 bits in 32 bits (although in AES specifications, the key length is only 128, 192 and 256 bits).

128bit = 16 bytes

192bit = 24 bytes

256bit = 32 bytes

The key length in the interface provided by go can only be 16 bytes

4.1. Encryption and Decryption of AES

Like DES, the AES algorithm consists of several rounds, and the following figure shows the general calculation steps for each round. DES uses the Feistel network as its basic structure, whereas AES does not use the Feistel network, but instead uses SPN Rijndael to group inputs into 128 bits, or 16 bytes. First, the 16-byte input data needs to be subBytes processed byte by byte. SubBytes refers to the process of finding the corresponding value from a replacement table (S-Box) with 256 values, indexed by the value of each byte (any value from 0 to 255), or by replacing one byte value with another.

SubBytes is then processed by ShiftRows, which shuffles the output of SubBytes in bytes. As we can see from the lines in the figure below, this disruption is handled regularly.

ShiftRows is then processed by MixCo1umns, which bits a 4-byte value into another 4-byte value.

Finally, you need to XOR the output of MixColumns with the wheel key, which is AddRoundKey. At this point, the AES round will end in the east. In fact, 10 to 14 rounds of calculations need to be repeated in AES.

From the above structure, we can see that all the bits entered will be encrypted in one round. The advantage of this approach over a Feistel network where only half of the input bits are encrypted in each round is that it requires fewer rounds to encrypt. Another advantage of this approach is that SubBytes, ShiftRows, and MixColumns can perform parallel calculations in bytes, rows, and columns, respectively.

4.2. Use of AES in Go

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
)

func main() {
	// encryption
	key := []byte("1234567812345678")
	result := AESEncrypt([]byte("yesyes hello world"), key)
	fmt.Println(base64.StdEncoding.EncodeToString(result))
	// Decrypt
	result = AESDecrypt(result, key)
	fmt.Println("Data after decryption: ", string(result))

}

// AESEncrypt AES Encryption
func AESEncrypt(src, key []byte) []byte {
	// 1. Create a block object using AES encryption
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	// 2. Last grouping for data filling
	src = PKCS5Padding(src, block.BlockSize())
	// 3. Create a block model object grouped in link mode with AES encryption at the bottom
	blockMode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
	// 4. Encryption
	dst := src
	blockMode.CryptBlocks(dst, src)
	return dst
}

// AESDecrypt AES Decryption
func AESDecrypt(src, key []byte) []byte {
	// 1. Create a block object that is decrypted using AES
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	// 2. Create groups into linked modes, underlying decryption model objects using AES
	blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
	// 3. Decryption
	dst := src
	blockMode.CryptBlocks(dst, src)
	// 4. Remove the word that fills the tail
	dst = PKCS5UnPadding(dst)
	return dst
}

// PKCS5Padding is populated using pks5
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	// 1. Calculate how many bytes are missing from the last group
	padding := blockSize - (len(ciphertext) % blockSize)
	// 2. Create a slice of padding size with a value of padding per byte
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	// 3. Add padText to the back of the original data to complete the missing bytes in the last group
	newText := append(ciphertext, padText...)
	return newText
}

// PKCS5UnPadding Deletes Tail Data Filled by pks5
func PKCS5UnPadding(origData []byte) []byte {
	// 1. Calculate the total length of the data
	length := len(origData)
	// 2. Number of times to get a fill based on the byte value of the fill
	number := int(origData[length-1])
	// 3. Remove the number bytes filled with the tail
	return origData[:(length - number)]
}

5. Which symmetric encryption should be selected

  1. It is better not to use DES for new purposes in the future, because with the progress of computer technology, it is now possible to decode DES by violence in real time. In some cases, however, compatibility with older versions of the software needs to be maintained.
  2. Triple DES will be used for some time in the future for compatibility reasons, but will be gradually replaced by AES.
  3. The algorithm you should use in the future is AES (Rijndael), because it is safe, fast and can work on a variety of platforms. In addition, since cryptographers around the world are constantly validating AES, they will immediately inform the world and fix any defects they find.

5. Which symmetric encryption should be selected

  1. It is better not to use DES for new purposes in the future, because with the progress of computer technology, it is now possible to decode DES by violence in real time. In some cases, however, compatibility with older versions of the software needs to be maintained.
  2. Triple DES will be used for some time in the future for compatibility reasons, but will be gradually replaced by AES.
  3. The algorithm you should use in the future is AES (Rijndael), because it is safe, fast and can work on a variety of platforms. In addition, since cryptographers around the world are constantly validating AES, they will immediately inform the world and fix any defects they find.

Generally speaking, instead of using any homemade cipher algorithm, we should use AES. Because AES has undergone high-quality validation by cryptographers around the world during its selection process, it is difficult to validate self-made cryptographic algorithms.

Tags: Go cryptology AES des

Posted by bradkenyon on Thu, 05 May 2022 19:08:46 +0300