Go base64 md5 sha256 codec and digest algorithm aes des sha1
During the project development process, when operating some users’ private information, such as passwords, account keys and other data, it often needs to be encrypted and transmitted on the Internet. At this time, some efficient and easy-to-use encryption algorithms are needed to encrypt the data, and then store the encrypted data in the database or perform other operations; when the data needs to be read, the encrypted data is taken out, and then decrypted by the algorithm .
package main
import (
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
)
func main() {
var str string = "hello world"
// md5
// 1.md5V1
h1 := md5.New()
h1.Write([]byte(str))
md5V1 := hex.EncodeToString(h1.Sum(nil))
fmt.Printf("md5V1: %s\n", md5V1)
// 2.md5V2
h2 := md5.Sum([]byte(str))
md5V2 := fmt.Sprintf("%x", h2)
fmt.Printf("md5V2: %s\n", md5V2)
// 3.md5V3
h3 := md5.New()
io.WriteString(h3, str)
md5V3 := fmt.Sprintf("%x", h3.Sum(nil))
fmt.Printf("md5V2: %s\n", md5V3)
/*
md5V1: 5eb63bbbe01eeed093cb22bb8f5acdc3
md5V2: 5eb63bbbe01eeed093cb22bb8f5acdc3
md5V2: 5eb63bbbe01eeed093cb22bb8f5acdc3
*/
// sha256
// 1.sha256V1
s1 := sha256.New()
s1.Write([]byte(str))
sha256v1 := hex.EncodeToString(s1.Sum(nil))
fmt.Printf("sha256v1: %s\n", sha256v1)
// 2.sha256V2
s2 := sha256.Sum256([]byte(str))
sha256V2 := fmt.Sprintf("%x", s2)
fmt.Printf("sha256v2: %s\n", sha256V2)
// 3.sha256V3
s3 := sha256.New()
s3.Write([]byte(str))
sha256V3 := fmt.Sprintf("%x", s3.Sum(nil))
fmt.Printf("sha256v3: %s\n", sha256V3)
/*
sha256v1: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
sha256v2: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
sha256v3: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
*/
// base64
// encode
encodeStr := base64.StdEncoding.EncodeToString([]byte(str))
fmt.Printf("base64 encode: %s\n", encodeStr)
// decode
decodeStr, err := base64.StdEncoding.DecodeString(encodeStr)
if err != nil {
fmt.Println(err)
}
fmt.Printf("base64 decode: %s\n", decodeStr)
/*
base64 encode: aGVsbG8gd29ybGQ=
base64 decode: hello world
*/
// uriencode -> 把“/”换成“_”,把“+”换成“-”
uriEncode := base64.URLEncoding.EncodeToString([]byte(str))
fmt.Printf("base64 uriencode: %s\n", uriEncode)
uriDecode, err := base64.URLEncoding.DecodeString(uriEncode)
if err != nil {
fmt.Println(err)
}
fmt.Printf("base64 uridecode: %s\n", uriDecode)
/*
base64 uriencode: aGVsbG8gd29ybGQ=
base64 uridecode: hello world
*/
}
AES AES, the Advanced Encryption Standard (Advanced Encryption Standard), is a symmetric block cipher algorithm designed to replace DES as the widely used standard. There are three common solutions in AES, namely AES-128, AES-192 and AES-256. The AES encryption process involves four operations: byte substitution (SubBytes), row shift (ShiftRows), column confusion (MixColumns) and round key addition (AddRoundKey). The decryption process is the corresponding inverse operation. Since each step of operation is reversible, the plaintext can be recovered by decrypting in reverse order. The key of each round in encryption and decryption is obtained by expanding the initial key. The 16-byte plaintext, ciphertext and round key in the algorithm are represented by a 4×4 matrix. AES has five encryption modes: Electronic Codebook Book (ECB) , Cipher Block Chaining (CBC) , Counter (CTR) , Cipher FeedBack (CFB )) and output feedback mode (Output FeedBack (OFB))
import (
"bytes"
"crypto/aes"
"fmt"
"crypto/cipher"
"encoding/base64"
)
func main() {
orig := "hello world"
key := "123456781234567812345678"
fmt.Println("Original:", orig)
encryptCode := AesEncrypt(orig, key)
fmt.Println("ciphertext:", encryptCode)
decryptCode := AesDecrypt(encryptCode, key)
fmt.Println("Decryption result:", decryptCode)
}
func AesEncrypt(orig string, key string) string {
// convert to byte array
origData := []byte(orig)
k := []byte(key)
// group key
block, _ := aes. NewCipher(k)
// Get the length of the key block
blockSize := block. BlockSize()
// completion code
origData = PKCS7Padding(origData, blockSize)
// encryption mode
blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
// create array
cryted := make([]byte, len(origData))
// encryption
blockMode. CryptBlocks(cryted, origData)
return base64.StdEncoding.EncodeToString(cryted)
}
func AesDecrypt(crypted string, key string) string {
// convert to byte array
crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
k := []byte(key)
// group key
block, _ := aes. NewCipher(k)
// Get the length of the key block
blockSize := block. BlockSize()
// encryption mode
blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
// create array
orig := make([]byte, len(crytedByte))
// decrypt
blockMode. CryptBlocks(orig, crytedByte)
// to complete the code
orig = PKCS7UnPadding(orig)
return string(orig)
}
//complement code
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
padding := blocksize - len(ciphertext)%blocksize
padtext := bytes. Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// to code
func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
DES DES is a symmetric encryption algorithm, also known as the American Data Encryption Standard. DES encrypts data in 64-bit blocks. Encryption and decryption use the same 64-bit key. In fact, only 56 bits of it are used, and the 8th, 16th…64th bits in the key Used for parity check. DES has encryption modes such as ECB (electronic codebook) and CBC (encrypted block). The security of the DES algorithm is very high. At present, there is no better way to crack it except exhaustive search. The longer the key length, the more difficult it is to crack. Fill and defill 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
}
RSA First, use openssl to generate public and private keys. When using RSA, you need to provide public and private keys. You can use openss to generate the corresponding public and private keys in pem format.
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
)
// 私钥生成
//openssl genrsa -out rsa_private_key.pem 1024
var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDcGsUIIAINHfRTdMmgGwLrjzfMNSrtgIf4EGsNaYwmC1GjF/bM
h0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdTnCDPPZ7oV7p1B9Pud+6zPaco
qDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Zy682X1+R1lRK8D+vmQIDAQAB
AoGAeWAZvz1HZExca5k/hpbeqV+0+VtobMgwMs96+U53BpO/VRzl8Cu3CpNyb7HY
64L9YQ+J5QgpPhqkgIO0dMu/0RIXsmhvr2gcxmKObcqT3JQ6S4rjHTln49I2sYTz
7JEH4TcplKjSjHyq5MhHfA+CV2/AB2BO6G8limu7SheXuvECQQDwOpZrZDeTOOBk
z1vercawd+J9ll/FZYttnrWYTI1sSF1sNfZ7dUXPyYPQFZ0LQ1bhZGmWBZ6a6wd9
R+PKlmJvAkEA6o32c/WEXxW2zeh18sOO4wqUiBYq3L3hFObhcsUAY8jfykQefW8q
yPuuL02jLIajFWd0itjvIrzWnVmoUuXydwJAXGLrvllIVkIlah+lATprkypH3Gyc
YFnxCTNkOzIVoXMjGp6WMFylgIfLPZdSUiaPnxby1FNM7987fh7Lp/m12QJAK9iL
2JNtwkSR3p305oOuAz0oFORn8MnB+KFMRaMT9pNHWk0vke0lB1sc7ZTKyvkEJW0o
eQgic9DvIYzwDUcU8wJAIkKROzuzLi9AvLnLUrSdI6998lmeYO9x7pwZPukz3era
zncjRK3pbVkv0KrKfczuJiRlZ7dUzVO0b6QJr8TRAA==
-----END RSA PRIVATE KEY-----
`)
// 公钥: 根据私钥生成
//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcGsUIIAINHfRTdMmgGwLrjzfM
NSrtgIf4EGsNaYwmC1GjF/bMh0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdT
nCDPPZ7oV7p1B9Pud+6zPacoqDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Z
y682X1+R1lRK8D+vmQIDAQAB
-----END PUBLIC KEY-----
`)
// 加密
func RsaEncrypt(origData []byte) ([]byte, error) {
//解密pem格式的公钥
block, _ := pem.Decode(publicKey)
if block == nil {
return nil, errors.New("public key error")
}
// 解析公钥
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// 类型断言
pub := pubInterface.(*rsa.PublicKey)
//加密
return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}
// 解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
//解密
block, _ := pem.Decode(privateKey)
if block == nil {
return nil, errors.New("private key error!")
}
//解析PKCS1格式的私钥
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
// 解密
return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
func main() {
data, _ := RsaEncrypt([]byte("hello world"))
fmt.Println(base64.StdEncoding.EncodeToString(data))
origData, _ := RsaDecrypt(data)
fmt.Println(string(origData))
}
MD5 The full name of MD5 is Message-DigestAlgorithm 5, which can convert a byte array of any length into a fixed-length integer, and this conversion is irreversible. For data of arbitrary length, the length of the converted MD5 value is fixed, and the conversion operation of MD5 is very easy. As long as the original data is slightly changed, the converted result will be very different. It is precisely because of these characteristics of the MD5 algorithm that it is often used to generate an information summary for a piece of information to prevent it from being tampered with. It is also widely used in the security verification during the login process of the operating system. For example, the password of the Unix operating system is encrypted by MD5 and stored in the file system. When the user enters the password when logging in, the data entered by the user is encrypted with MD5 Compare the original stored ciphertext information, if they are the same, the password is correct, otherwise the entered password is wrong. MD5 groups data with 512 bits as a calculation unit, and each group is divided into 16 32-bit groups. After a series of processing, it outputs 4 32-bit groups, and finally forms a 128-bit hash value. . Perform 512 remainder on the processed data to get N and a remainder. If the remainder is not 448, fill in 1 and several 0s until 448 bits, and finally add a 64-bit to save 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, and the Check function passes in an unencrypted string and compares it with 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))
}
//测试。
func main() {
strTest := "I love this beautiful world!"
strEncrypted := "98b4fc4538115c4980a8b859ff3d27e1"
fmt.Println(Check(strTest, strEncrypted))
}
//Output:
//true
SHA1
package main
import (
"crypto/sha1"
"fmt"
)
func main() {
s := "sha1 this string"
//The way to generate a hash value is sha1.New(), sha1.Write(bytes), then sha1.Sum([]byte{}). Here we start with a new hash.
h := sha1.New()
// Write the bytes to process. If it is a string, you need to use []byte(s) to cast it into a byte array.
h.Write([]byte(s))
// This character slice is used to get the final hash value. The Sum argument can be used to append an additional byte slice to an existing character slice: generally not needed.
bs := h.Sum(nil)
//SHA1 values are often output in hex, e.g. in git commits. Use %x to format the hash result as a hexadecimal string.
fmt. Println(s)
fmt.Printf("%x\n", bs)
}
Base64
Base64 is an encoding method from any binary to a text string, and is often used to transmit a small amount of binary data in URLs, cookies, and web pages. First, using Base64 encoding requires a table containing 64 characters, which consists of uppercase and lowercase letters, numbers, + and /. When using Base64 encoding to process data, every three bytes with a total of 24 bits will be regarded as a processing unit, and then divided into four groups of 6 bits, and the corresponding characters are obtained after looking up the table, which is the encoded string. The encoded string is 32 bits long, so after Base64 encoding, the original string is increased by 1/3. If the data to be encoded is not a multiple of 3, there will be one or two bytes left at the end. In Base64 encoding, \x00 will be used to complete after the processing unit, and one or two = will be added at the end of the encoded string to indicate A few bytes have been added.
const (
base64Table = "IJjkKLMNO567PQX12RVW3YZaDEFGbcdefghiABCHlSTUmnopqrxyz04stuvw89+/"
)
var coder = base64. NewEncoding(base64Table)
func Base64Encode(src []byte) []byte { //encode
return []byte(coder. EncodeToString(src))
}
func Base64Decode(src []byte) ([]byte, error) { //decode
return coder. DecodeString(string(src))
}