package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io" ) // GetGCM // @description 获取GCM密码器 // @return gcm cipher.AEAD GCM密码器 func GetGCM() (gcm cipher.AEAD) { // 加解或解密所需的密钥 // 密钥有长度限制,使用不同长度密钥会选择不同算法,对应关系如下: // 密钥长度为16个字节:使用“AES-128”算法 // 密钥长度为24个字节:使用“AES-192”算法 // 密钥长度为32个字节:使用“AES-256”算法 // 如果密钥长度不是16、24、32就会报错 key := "12345678901234567890123456789012" block, err := aes.NewCipher([]byte(key)) if err != nil { panic(err) } gcm, err = cipher.NewGCM(block) if err != nil { panic(err) } return } // Encrypt // @description 加密 // @param msg string 要加密的消息 // @return ciphertext string 密文(重要提醒:密文包括消息和随机数两部分,解密时需要先将它们提取出来) func Encrypt(msg string) (ciphertext string) { gcm := GetGCM() // 获取GCM密码器 // 生成随机数用于加密,这样相同消息每次加密都会产生不同密文,注意解密也必须使用该随机数 nonce := make([]byte, gcm.NonceSize()) _, err := io.ReadFull(rand.Reader, nonce) if err != nil { panic(err) } // 加密 encrypt := gcm.Seal(nil, nonce, []byte(msg), nil) // 原始密文和随机数都是一串乱码,将其编码方便传输和保存,这里采用十六进制编 // 码,也可以根据需求选择其它编码方式(如base64编码),注意解密时需要先解码。 ciphertext = hex.EncodeToString(encrypt) + hex.EncodeToString(nonce) // 消息+随机数 return } // Decrypt // @description 解密 // @param ciphertext string 密文(重要提醒:密文包括消息和随机数两部分,解密时需要先将它们提取出来) // @return plaintext string 明文 func Decrypt(ciphertext string) (plaintext string) { gcm := GetGCM() // 获取GCM密码器 // 提取出随机数和密文 nonce := ciphertext[len(ciphertext)-gcm.NonceSize()*2:] // 随机数 ciphertext = ciphertext[:len(ciphertext)-gcm.NonceSize()*2] // 密文 // 解码密文 ciphertextByte, err := hex.DecodeString(ciphertext) if err != nil { panic(err) } // 解码随机数 nonceByte, err := hex.DecodeString(nonce) if err != nil { panic(err) } // 解密 decrypt, err := gcm.Open(nil, nonceByte, ciphertextByte, nil) if err != nil { panic(err) } plaintext = string(decrypt) return } func main() { // ========== 要加密的消息 ========== // msg := "PHP是世界上最好の语言" // ========== 加密 ========== // ciphertext := Encrypt(msg) // 每次产生的密文均不相同 fmt.Printf("密文:%+v \n", ciphertext) // 密文:9bb9b9cf197d077bdf835d97ad3f54ca28caf54…… // ========== 解密 ========== // plaintext := Decrypt(ciphertext) fmt.Printf("明文:%+v \n", plaintext) // 明文:PHP是世界上最好の语言 }
Copyright © 2024 码农人生. All Rights Reserved