> AES : 高级加密标准;AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特;
```
type AES interface {
Encrypt(str, key []byte) ([]byte, error)
Decrypt(str, key []byte) ([]byte, error)
}
```
---
> DES : 数据加密标准,是一种使用密钥加密的块算法
```
type DES interface {
Encrypt(str, key []byte) ([]byte, error)
Decrypt(str, key []byte) ([]byte, error)
}
```
---
> AES&DES 支持的模式: CBC 密码分组链接模式(Cipher Block Chaining (CBC))
```
// CBC : 密码分组链接模式(Cipher Block Chaining (CBC)) default
type cbcObj struct {
cryptoType string
iv []byte
}
func (cbc *cbcObj) getBlock(key []byte) (block cipher.Block, err error) {
if cbc.cryptoType == "aes" {
block, err = aes.NewCipher(key)
}
if cbc.cryptoType == "des" {
block, err = des.NewCipher(key)
}
return
}
// CBC Encrypt
func (cbc *cbcObj) Encrypt(str, key []byte) ([]byte, error) {
block, err := cbc.getBlock(key)
if err != nil {
Error("["+cbc.cryptoType+"-CBC] ERROR:" +err.Error())
return []byte(""), err
}
blockSize := block.BlockSize()
originData := cbc.pkcs5Padding(str, blockSize)
blockMode := cipher.NewCBCEncrypter(block,cbc.iv)
cryptData := make([]byte,len(originData))
blockMode.CryptBlocks(cryptData,originData)
P2E()
return cryptData, nil
}
// CBC Decrypt
func (cbc *cbcObj) Decrypt(str, key []byte) ([]byte, error) {
block, err := cbc.getBlock(key)
if err != nil {
Error("["+cbc.cryptoType+"-CBC] ERROR:" +err.Error())
return []byte(""), err
}
blockMode := cipher.NewCBCDecrypter(block, cbc.iv)
originStr := make([]byte,len(str))
blockMode.CryptBlocks(originStr,str)
P2E()
return cbc.pkcs5UnPadding(originStr), nil
}
func (cbc *cbcObj) pkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padText...)
}
func (cbc *cbcObj) pkcs5UnPadding(origData []byte) []byte {
length := len(origData)
unpadDing := int(origData[length-1])
return origData[:(length - unpadDing)]
}
```
---
> AES&DES 支持的模式: ECB 电码本模式(Electronic Codebook Book (ECB))
```
// ECB : 电码本模式(Electronic Codebook Book (ECB))
type ecbObj struct {
cryptoType string
}
func (ecb *ecbObj) getBlock(key []byte) (block cipher.Block, err error) {
if ecb.cryptoType == "aes" {
block, err = aes.NewCipher(ecb.generateKey(key))
}
if ecb.cryptoType == "des" {
block, err = des.NewCipher(key)
}
return
}
// ECB Encrypt
func (ecb *ecbObj) Encrypt(str, key []byte) ([]byte, error) {
block, err := ecb.getBlock(key)
if err != nil {
Error("["+ecb.cryptoType+"-ECB] ERROR:" +err.Error())
return []byte(""), err
}
blockSize := block.BlockSize()
if ecb.cryptoType == "aes" {
str = ecb.pkcs5PaddingAes(str, blockSize)
}
if ecb.cryptoType == "des" {
str = ecb.pkcs5PaddingDes(str, blockSize)
}
//返回加密结果
encryptData := make([]byte, len(str))
//存储每次加密的数据
tmpData := make([]byte, blockSize)
//分组分块加密
for index := 0; index < len(str); index += blockSize {
block.Encrypt(tmpData, str[index:index+blockSize])
copy(encryptData, tmpData)
}
P2E()
return encryptData, nil
}
func (ecb *ecbObj) pkcs5PaddingDes(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func (ecb *ecbObj) pkcs5PaddingAes(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
if padding != 0 {
ciphertext = append(ciphertext, bytes.Repeat([]byte{byte(0)}, padding)...)
}
return ciphertext
}
// ECB Decrypt
func (ecb *ecbObj) Decrypt(str, key []byte) ([]byte, error) {
block, err := ecb.getBlock(key)
if err != nil {
Error("["+ecb.cryptoType+"-ECB] ERROR:" +err.Error())
return []byte(""), err
}
blockSize := block.BlockSize()
//返回加密结果
decryptData := make([]byte, len(str))
//存储每次加密的数据
tmpData := make([]byte, blockSize)
//分组分块加密
for index := 0; index < len(str); index += blockSize {
block.Decrypt(tmpData, str[index:index+blockSize])
copy(decryptData, tmpData)
}
if ecb.cryptoType == "des" {
return ecb.pkcs5UnPadding(decryptData), nil
}
P2E()
return ecb.unPadding(decryptData), nil
}
func (ecb *ecbObj) generateKey(key []byte) (genKey []byte) {
genKey = make([]byte, 16)
copy(genKey, key)
for i := 16; i < len(key); {
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 {
genKey[j] ^= key[i]
}
}
return genKey
}
func (ecb *ecbObj) unPadding(src []byte) []byte {
for i := len(src) - 1; ; i-- {
if src[i] != 0 {
return src[:i+1]
}
}
}
func (ecb *ecbObj) pkcs5UnPadding(origData []byte) []byte {
length := len(origData)
unPadding := int(origData[length-1])
return origData[:(length - unPadding)]
}
```
---
> AES&DES 支持的模式: CFB : 密码反馈模式(Cipher FeedBack (CFB))
```
// 密码反馈模式(Cipher FeedBack (CFB))
type cfbObj struct {
cryptoType string
}
func (cfb *cfbObj) getBlock(key []byte) (block cipher.Block, err error) {
if cfb.cryptoType == "aes" {
block, err = aes.NewCipher(key)
}
if cfb.cryptoType == "des" {
block, err = des.NewCipher(key)
}
return
}
// CFB Encrypt
func (cfb *cfbObj) Encrypt(str, key []byte) ([]byte, error) {
P2E()
block, err := cfb.getBlock(key)
if err != nil {
Error("["+cfb.cryptoType+"-CFB] ERROR:" +err.Error())
return nil, err
}
if cfb.cryptoType == "aes" {
encrypted := make([]byte, aes.BlockSize+len(str))
iv := encrypted[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[aes.BlockSize:], str)
return encrypted, nil
}
if cfb.cryptoType == "des" {
encrypted := make([]byte, des.BlockSize+len(str))
iv := encrypted[:des.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[des.BlockSize:], str)
return encrypted, nil
}
return nil, nil
}
// CFB Decrypt
func (cfb *cfbObj) Decrypt(str, key []byte) ([]byte, error) {
P2E()
block, err := cfb.getBlock(key)
if err != nil {
Error("["+cfb.cryptoType+"-CFB] ERROR:" +err.Error())
return nil, err
}
iv := []byte{}
if cfb.cryptoType == "aes" {
if len(str) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
iv = str[:aes.BlockSize]
str = str[aes.BlockSize:]
}
if cfb.cryptoType == "des" {
if len(str) < des.BlockSize {
return nil, errors.New("ciphertext too short")
}
iv = str[:des.BlockSize]
str = str[des.BlockSize:]
}
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(str, str)
return str, nil
}
```
---
> AES&DES 支持的模式: CTR 计算器模式(Counter (CTR))
```
// 计算器模式(Counter (CTR))
type ctrObj struct {
count []byte //指定计数器,长度必须等于block的块尺寸
cryptoType string
}
func (ctr *ctrObj) getBlock(key []byte) (block cipher.Block, err error) {
if ctr.cryptoType == "aes" {
block, err = aes.NewCipher(key)
}
if ctr.cryptoType == "des" {
block, err = des.NewCipher(key)
if len(ctr.count) > des.BlockSize {
ctr.count = ctr.count[0:des.BlockSize]
}
}
return
}
// CTR Encrypt
func (ctr *ctrObj) Encrypt(str, key []byte) ([]byte, error) {
return ctr.crypto(str, key)
}
// CTR Decrypt
func (ctr *ctrObj) Decrypt(str, key []byte) ([]byte, error) {
return ctr.crypto(str, key)
}
func (ctr *ctrObj) crypto(str, key []byte) ([]byte, error) {
P2E()
block,err:=ctr.getBlock(key)
if err != nil {
Error("[AES-CTR] ERROR:" +err.Error())
return []byte(""), err
}
//指定分组模式
blockMode:=cipher.NewCTR(block, ctr.count)
//执行加密、解密操作
res:=make([]byte,len(str))
blockMode.XORKeyStream(res,str)
//返回明文或密文
return res, nil
}
```
---
> AES&DES 支持的模式: OFB : 输出反馈模式(Output FeedBack (OFB))
```
// 输出反馈模式(Output FeedBack (OFB))
type ofbObj struct {}
```
---
> Hmac 是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。
```
func hmacFunc(h func() hash.Hash, str, key []byte) string {
mac := hmac.New(h, key)
mac.Write(str)
res := base64.StdEncoding.EncodeToString(mac.Sum(nil))
return res
}
// HmacMD5
func HmacMD5(str, key string) string {
return hmacFunc(md5.New, []byte(str), []byte(key))
}
// HmacSHA1
func HmacSHA1(str, key string) string {
return hmacFunc(sha1.New, []byte(str), []byte(key))
}
// HmacSHA256
func HmacSHA256(str, key string) string {
return hmacFunc(sha256.New, []byte(str), []byte(key))
}
// HmacSHA512
func HmacSHA512(str, key string) string {
return hmacFunc(sha512.New, []byte(str), []byte(key))
}
```
---
> PBKDF2应用一个伪随机函数以导出密钥
```
func pbkdf2Func(h func() hash.Hash, str, salt []byte, iterations, keySize int) []byte {
return pbkdf2.Key(str, salt, iterations, keySize, h)
}
// PBKDF2
func PBKDF2(str, salt []byte, iterations, keySize int) ([]byte) {
return pbkdf2Func(sha256.New, str, salt, iterations, keySize)
}
```
---
> JWT: JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简介的、自包含的协议格式,用于
在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公
钥/私钥对来签名,防止被篡改。
```
// jwtEncrypt
func jwtEncrypt(token *jwt.Token, data map[string]interface{}, secret string) (string, error) {
claims := make(jwt.MapClaims)
for k, v := range data {
claims[k] = v
}
token.Claims = claims
return token.SignedString([]byte(secret))
}
// JwtEncrypt
func JwtEncrypt(data map[string]interface{}, secret, method string) (string, error){
switch method {
case "256":
return jwtEncrypt(jwt.New(jwt.SigningMethodHS256), data, secret)
case "384":
return jwtEncrypt(jwt.New(jwt.SigningMethodHS384), data, secret)
case "512":
return jwtEncrypt(jwt.New(jwt.SigningMethodHS512), data, secret)
}
return "",fmt.Errorf("未知method; method= 256 or 384 or 512 ")
}
// JwtEncrypt256
func JwtEncrypt256(data map[string]interface{}, secret string) (string, error){
token := jwt.New(jwt.SigningMethodHS256)
return jwtEncrypt(token, data, secret)
}
// JwtEncrypt384
func JwtEncrypt384(data map[string]interface{}, secret string) (string, error){
token := jwt.New(jwt.SigningMethodHS384)
return jwtEncrypt(token, data, secret)
}
// JwtEncrypt512
func JwtEncrypt512(data map[string]interface{}, secret string) (string, error){
token := jwt.New(jwt.SigningMethodHS512)
return jwtEncrypt(token, data, secret)
}
// JwtDecrypt
func JwtDecrypt(tokenString, secret string) (data map[string]interface{}, err error) {
data = make(map[string]interface{})
var secretFunc = func() jwt.Keyfunc { //按照这样的规则解析
return func(t *jwt.Token) (interface{}, error) {
return []byte(secret), nil
}
}
token, err := jwt.Parse(tokenString, secretFunc())
if err != nil {
err = fmt.Errorf("未知Token")
return
}
claim, ok := token.Claims.(jwt.MapClaims)
if !ok {
return
}
if !token.Valid {
// 令牌错误
return
}
for k, v := range claim {
data[k] =v
}
return
}
```
其它: Rabbit, RC4, RIPEMD-160, DSA, RSA
### 源码传送门
https://github.com/mangenotwork/gathertool/blob/main/crypto.go
有疑问加站长微信联系(非本文作者))