This is a creation in Article, where the information may have evolved or changed.
During the project development process, when we use the database to store some information about the user's privacy, such as passwords, account keys and other data, it needs to be encrypted before writing to the database. At this point, we need some efficient, easy-to-use encryption algorithm, when we write data to the database to encrypt data, and then put the encrypted data into the database, when the need to read data, from the database after the encrypted data removed, and then decrypted by the algorithm.
Common cryptographic algorithms are Base64, MD5, AES, and Des.
Base64
Base64 is an arbitrary binary-to-text string encoding method that is commonly used to transmit small amounts of binary data in URLs, cookies, and Web pages.
The first use of BASE64 encoding requires a 64-character table, which consists of uppercase and lowercase letters, numbers, + and/. When using BASE64 encoding to process data, each three bytes of 24 bits is treated as a processing unit, divided into four groups, 6 bits per group, and the corresponding characters are obtained after the table is encoded as a string. The encoded string is 32 bits long, so that after BASE64 encoding, the original string grows by 1/3. If the data to be encoded is not a multiple of 3, and the last one to two bytes, the BASE64 encoding will be used \x00 in the processing unit after the completion of the encoded string will be added to the end of one to two = The number of bytes is added.
Base64 table
BASE64Table = "IJjkKLMNO567PQX12RVW3YZaDEFGbcdefghiABCHlSTUmnopqrxyz04stuvw89+/"
Encryption. The second line of code in the function converts an input string into a byte array.
func Encode(data string) string { content := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&data)))) coder := base64.NewEncoding(BASE64Table) return coder.EncodeToString(content)}
Decrypt. The code at the return of the function can convert a byte array into a string.
func Decode(data string) string { coder := base64.NewEncoding(BASE64Table) result, _ := coder.DecodeString(data) return *(*string)(unsafe.Pointer(&result))}
Test.
func main(){ strTest := "I love this beautiful world!" strEncrypt := Encode(strTest) strDecrypt := Decode(strEncrypt) fmt.Println("Encrypted:",strEncrypt) fmt.Println("Decrypted:",strDecrypt) }//Output://Encrypted: VVJmGsEBONRlFaPfDCYgcaRSEHYmONcpbCrAO2==//Decrypted: I love this beautiful world!
MD5
The full name of MD5 is Message-digestalgorithm 5, which converts an arbitrary-length byte array into an integer of fixed length, and the conversion is irreversible. For any length of data, the converted MD5 value length is fixed, and the MD5 conversion operation is very easy, as long as the original data has a little change, the results will be very large difference. Precisely because of these features of the MD5 algorithm, it is often used to generate information summaries for a piece of information to prevent it from being tampered with. It is also widely in the operating system login process of security verification, such as the UNIX operating system password is MD5 encrypted after the storage to the file system, when the user entered the password, the user entered the data after the MD5 encryption and the original stored ciphertext information, if the same instructions password is correct, Otherwise, the password entered is wrong.
MD5 groups The data in 512-bit units, and each grouping is divided into 16 32-bit groups, which, after a series of processing, outputs 4 32-bit groups and finally composes a 128-bit hash value. 512 of the processed data is obtained N and a remainder, if the remainder is not 448, padding 1 and a number of 0 until 448 bits, and finally a 64 bit to hold the length of the data, so after preprocessing, the data becomes (N+1) x 512 bits.
Encryption. The Encode function is used to encrypt data, the check function passes in an unencrypted string and compares it to the encrypted data, and returns True if it is correct.
func Check(content, encrypted string) bool { return strings.EqualFold(Encode(content), encrypted)}func Encode(data string) string { h := md5.New() h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil))}
Test.
func main() { strTest := "I love this beautiful world!" strEncrypted := "98b4fc4538115c4980a8b859ff3d27e1" fmt.Println(Check(strTest, strEncrypted))}//Output://true
Des
Des is a symmetric encryption algorithm, also known as the United States data encryption standards. Des encryption in 64-bit packet encryption, encryption and decryption are using the same length of 64-bit key, in fact, only the 56 bits, the key of the 8th, 16...64 bits used for parity check. Des has an ECB (electronic cipher) and CBC (encryption block) and other cryptographic modes.
Des algorithm security is very high, at present, in addition to exhaustive search cracked, there is no better way to crack. The longer the key length, the greater the difficulty of cracking.
Fill and go to fill functions.
func ZeroPadding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{0}, padding) return append(ciphertext, padtext...)}func ZeroUnPadding(origData []byte) []byte { return bytes.TrimFunc(origData, func(r rune) bool { return r == rune(0) })}
Encryption.
func Encrypt(text string, key []byte) (string, error) { src := []byte(text) block, err := des.NewCipher(key) if err != nil { return "", err } bs := block.BlockSize() src = ZeroPadding(src, bs) if len(src)%bs != 0 { return "", errors.New("Need a multiple of the blocksize") } out := make([]byte, len(src)) dst := out for len(src) > 0 { block.Encrypt(dst, src[:bs]) src = src[bs:] dst = dst[bs:] } return hex.EncodeToString(out), nil}
Decrypt.
func Decrypt(decrypted string , key []byte) (string, error) { src, err := hex.DecodeString(decrypted) if err != nil { return "", err } block, err := des.NewCipher(key) if err != nil { return "", err } out := make([]byte, len(src)) dst := out bs := block.BlockSize() if len(src)%bs != 0 { return "", errors.New("crypto/cipher: input not full blocks") } for len(src) > 0 { block.Decrypt(dst, src[:bs]) src = src[bs:] dst = dst[bs:] } out = ZeroUnPadding(out) return string(out), nil}
Test. Here, the key that is used in Des is only 8 bits.
func main() { key := []byte("2fa6c1e9") str :="I love this beautiful world!" strEncrypted, err := Encrypt(str, key) if err != nil { log.Fatal(err) } fmt.Println("Encrypted:", strEncrypted) strDecrypted, err := Decrypt(strEncrypted, key) if err != nil { log.Fatal(err) } fmt.Println("Decrypted:", strDecrypted)}//Output://Encrypted: 5d2333b9fbbe5892379e6bcc25ffd1f3a51b6ffe4dc7af62beb28e1270d5daa1//Decrypted: I love this beautiful world!
Aes
AES, the Advanced Encryption Standard (encryption), is a symmetric block cipher algorithm designed to replace des as a widely used standard. There are three solutions commonly found in AES, AES-128, AES-192, and AES-256, respectively.
The AES encryption process involves 4 operations: byte substitution (subbytes), Row Shift (Shiftrows), column obfuscation (mixcolumns), and wheel key Plus (AddRoundKey). The decryption process is the corresponding inverse operation respectively. Since each step is reversible, decrypting in reverse order restores the plaintext. Each round of the encryption key is extended by the initial key, respectively. The 16-byte plaintext, ciphertext, and wheel keys in the algorithm are represented by a 4x4 matrix.
AES has five encryption modes: Code mode (Electronic Codebook Book (ECB)), Cipher packet link mode (Cipher Block Chaining (CBC)), Calculator mode (Counter (CTR)), The password feedback mode (Cipher FeedBack (CFB)) and output feedback mode (outputs FeedBack (OFB)). The following is a case of CFB.
Encryption. The IV is the initial vector, where the first 16 bits of the key are taken as the initial vectors.
func Encrypt(text string, key []byte) (string, error) { var iv = key[:aes.BlockSize] encrypted := make([]byte, len(text)) block, err := aes.NewCipher(key) if err != nil { return "", err } encrypter := cipher.NewCFBEncrypter(block, iv) encrypter.XORKeyStream(encrypted, []byte(text)) return hex.EncodeToString(encrypted), nil}
Decrypt.
func Decrypt(encrypted string, key []byte) (string, error) { var err error defer func() { if e := recover(); e != nil { err = e.(error) } }() src, err := hex.DecodeString(encrypted) if err != nil { return "", err } var iv = key[:aes.BlockSize] decrypted := make([]byte, len(src)) var block cipher.Block block, err = aes.NewCipher([]byte(key)) if err != nil { return "", err } decrypter := cipher.NewCFBDecrypter(block, iv) decrypter.XORKeyStream(decrypted, src) return string(decrypted), nil}
Test. Key keys can only be 16-, 24-, or 32-bit, corresponding to AES-128, AES-192, and AES-256 respectively.
func main(){ str := "I love this beautiful world!" key := []byte{0xBA, 0x37, 0x2F, 0x02, 0xC3, 0x92, 0x1F, 0x7D, 0x7A, 0x3D, 0x5F, 0x06, 0x41, 0x9B, 0x3F, 0x2D, 0xBA, 0x37, 0x2F, 0x02, 0xC3, 0x92, 0x1F, 0x7D, 0x7A, 0x3D, 0x5F, 0x06, 0x41, 0x9B, 0x3F, 0x2D, } strEncrypted,err := Encrypt(str, key) if err != nil { log.Error("Encrypted err:",err) } fmt.Println("Encrypted:",strEncrypted) strDecrypted,err := Decrypt(strEncrypted, key) if err != nil { log.Error("Decrypted err:",err) } fmt.Println("Decrypted:",strDecrypted)}//Output://Encrypted: f866bfe2a36d5a43186a790b41dc2396234dd51241f8f2d4a08fa5dc//Decrypted: I love this beautiful world!
Reference
- Des Crypto-ECB mode in Golang
- AES Five encryption modes (CBC, ECB, CTR, OCF, CFB)