密码学里目前有两大经典算法,一个是对称加解密,其中具有代表性的是 AES 加解密;另一个是非对称加解密,其中具有代表性的是 RSA 加解密。这里就以这两个经典算法为例,简单介绍一下其在Go语言中的实现。
AES 加解密
AES 加密又分为 ECB、CBC、CFB、OFB 等几种,这里只列两种吧。
1) CBC 加解密
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
func main() {
orig := ""
key := "123456781234567812345678"
fmt.Println("原文:", orig)
encryptCode := AesEncrypt(orig, key)
fmt.Println("密文:", encryptCode)
decryptCode := AesDecrypt(encryptCode, key)
fmt.Println("解密结果:", decryptCode)
}
func AesEncrypt(orig string, key string) string {
// 转成字节数组
origData := []byte(orig)
k := []byte(key)
// 分组秘钥
block, _ := aes.NewCipher(k)
// 获取秘钥块的长度
blockSize := block.BlockSize()
// 补全码
origData = PKCS7Padding(origData, blockSize)
// 加密模式
blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
// 创建数组
cryted := make([]byte, len(origData))
// 加密
blockMode.CryptBlocks(cryted, origData)
return base64.StdEncoding.EncodeToString(cryted)
}
func AesDecrypt(cryted string, key string) string {
// 转成字节数组
crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
k := []byte(key)
// 分组秘钥
block, _ := aes.NewCipher(k)
// 获取秘钥块的长度
blockSize := block.BlockSize()
// 加密模式
blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
// 创建数组
orig := make([]byte, len(crytedByte))
// 解密
blockMode.CryptBlocks(orig, crytedByte)
// 去补全码
orig = PKCS7UnPadding(orig)
return string(orig)
}
//补码
func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
padding := blocksize - len(ciphertext)%blocksize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
//去码
func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
其运行结果如下:
go run main.go
原文:
密文: m6bjY+Z9O8LPwT8nYPZ9/41JG7+k5PXxtENxYwnrii0=
解密结果:
go run main.go
=>757fbec27b304698750a3542896e8bc5b5d49ac7dba6c589a2ec35778bca
757fbec27b304698750a3542896e8bc5b5d49ac7dba6c589a2ec35778bca=>
package main import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io" ) func ExampleNewCFBDecrypter() { key, _ := hex.DecodeString("6368616e676520746869732070617373") ciphertext, _ := hex.DecodeString("939e08921a34ebc7d921c641edb55916c24cc2fa6f14e91b66c22a70c38d23e588c2aed3548cad5ab4baa63a214a") block, err := aes.NewCipher(key) if err != nil { panic(err) } if len(ciphertext) < aes.BlockSize { panic("ciphertext too short") } iv := ciphertext[:aes.BlockSize] ciphertext = ciphertext[aes.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) stream.XORKeyStream(ciphertext, ciphertext) fmt.Printf("%s\n", ciphertext) } func ExampleNewCFBEncrypter() { key, _ := hex.DecodeString("6368616e676520746869732070617373") plaintext := []byte("") block, err := aes.NewCipher(key) if err != nil { panic(err) } ciphertext := make([]byte, aes.BlockSize+len(plaintext)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } stream := cipher.NewCFBEncrypter(block, iv) stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext) fmt.Printf("%x\n", ciphertext) } func main() { ExampleNewCFBDecrypter() ExampleNewCFBEncrypter() } 运行结果如下: