Go 常用加密算法

Hash算法

md5

package main

import (
	"crypto/md5"
	"fmt"
)

func main() {
	hash := md5.New()
	hash.Write([]byte("abc"))
	fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:900150983cd24fb0d6963f7d28e17f72
}

SHA256

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	hash := sha256.New()
	hash.Write([]byte("abc"))
	fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
}

SHA512

package main

import (
	"crypto/sha512"
	"fmt"
)

func main() {
	hash := sha512.New()
	hash.Write([]byte("abc"))
	fmt.Printf("hash:%x\n", hash.Sum(nil)) //hash:hash:ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
}

hmac

hmac 依赖于其它hash算法,在hash算法的基础上引入了秘钥的概念,根据秘钥的不同,来生成不同的hash结果

package main

import (
	"crypto/hmac"
	"crypto/md5"
	"fmt"
)

func main() {
	example := []byte("abc")
	hash := hmac.New(md5.New, []byte("ak47"))
	hash.Write(example)
	hash2 := md5.New()
	hash2.Write(example)
	if fmt.Sprintf("%x", hash.Sum(nil)) != fmt.Sprintf("%x", hash2.Sum(nil)) {
		fmt.Println("hmac != hash") //hmac != hash
	}
}

对称加密算法

DES

要求key为8字节,加解密数据也为8字节

package main

import (
	"crypto/des"
	"fmt"
)

func main() {
	cipher, err := des.NewCipher([]byte("12345678"))
	if err != nil {
		panic(err)
	}

	EncryptResult := make([]byte, 8)
	DecryptResult := make([]byte, 8)
	plain := []byte("87654321")
	cipher.Encrypt(EncryptResult, plain)
	cipher.Decrypt(DecryptResult, EncryptResult)
	fmt.Println(plain)         //[56 55 54 53 52 51 50 49]
	fmt.Println(EncryptResult) //[56 84 48 40 155 117 148 36]
	fmt.Println(DecryptResult) //[56 55 54 53 52 51 50 49]
}

3DES

在DES的基础上,总共进行三次DES加解密,提升DES的安全性,增加暴力破解难度,由于进行三次加解密,所以需要提供24字节的key

package main

import (
	"crypto/des"
	"fmt"
)

func main() {
	cipher, err := des.NewTripleDESCipher([]byte("123456781994011319960626"))
	if err != nil {
		panic(err)
	}

	EncryptResult := make([]byte, 8)
	DecryptResult := make([]byte, 8)
	plain := []byte("87654321")
	cipher.Encrypt(EncryptResult, plain)
	cipher.Decrypt(DecryptResult, EncryptResult)
	fmt.Println(plain)         //[56 55 54 53 52 51 50 49]
	fmt.Println(EncryptResult) //[48 100 4 163 34 141 1 112]
	fmt.Println(DecryptResult) //[56 55 54 53 52 51 50 49]
}                                                                                                                                                                                                                                          

AES

AES需要 (16,24,32)字节的key和16字节的data

package main

import (
	"crypto/aes"
	"fmt"
)

func main() {
	var (
		encryptResult = make([]byte, 16)
		key           = []byte("1234567812345678")
		source        = []byte("1111222233334444")
	)

	cipher, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	cipher.Encrypt(encryptResult, source)
	fmt.Println(encryptResult) //[50 50 164 142 39 30 55 128 22 114 255 134 72 22 134 162]
}

如果加密数据超过16位,那么就要使迭代模式了,下面代码展示了使用CBC模式对32字节的数据进行加解密

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"fmt"
)

func main() {
	var (
		key           = []byte("1234567812345678")
		source        = []byte("11112222333344441111222233334444")
		encryptResult = make([]byte, 32)
		decryptResult = make([]byte, 32)
		iv            = make([]byte, 16)
	)

	cipherBlock, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	encrypter := cipher.NewCBCEncrypter(cipherBlock, iv)
	encrypter.CryptBlocks(encryptResult, source)
	decrypter := cipher.NewCBCDecrypter(cipherBlock, iv)
	decrypter.CryptBlocks(decryptResult, encryptResult)
	fmt.Println(encryptResult) //[50 50 164 142 39 30 55 128 22 114 255 134 72 22 134 162]
	fmt.Println(decryptResult) //[49 49 49 49 50 50 50 50 51 51 51 51 52 52 52 52 49 49 49 49 50 50 50 50 51 51 5 1 51 52 52 52 52]
	fmt.Println(source)        //[49 49 49 49 50 50 50 50 51 51 51 51 52 52 52 52 49 49 49 49 50 50 50 50 51 51 5 1 51 52 52 52 52]
}

通常我们再迭代模式中,会将每16字节分成一个块,如果某个块不足16字节,会对其进行填充
填充方法:

package main

import (
    "bytes"
    "fmt"
)

func Pkcs5Padding(source []byte) []byte {
    padding := 16 - len(source)%16
    paddingBytes := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(source, paddingBytes...)
}

func main() {
    padding := Pkcs5Padding([]byte("abc"))
    fmt.Println(padding)
}

移除填充:

package main

import (
	"bytes"
	"fmt"
)

func Pkcs5Padding(source []byte) []byte {
	padding := 16 - len(source)%16
	paddingBytes := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(source, paddingBytes...)
}

func UnPkcs5Padding(source []byte) []byte {
	unPadding := int(source[len(source)-1])
	return source[:(len(source) - unPadding)]
}

func main() {
	padding := Pkcs5Padding([]byte("abc"))
	fmt.Println(padding) //[97 98 99 13 13 13 13 13 13 13 13 13 13 13 13 13]
	unPadding := UnPkcs5Padding(padding)
	fmt.Println(unPadding) //[97 98 99]
}

非对称加密

非对称加密生成两个不同的key(公钥,私钥)
公钥加密的私钥可以解,私钥加密的公钥可以解
生成私钥:

 openssl genrsa -out private.pem 2048

image.png
生成对应公钥:

openssl rsa -in private.pem -outform PEM -pubout -out public.pem

image.png

签名验签

私钥签名:

func RsaSign(plainText []byte) []byte {
	open, err := os.Open("private.pem")
	if err != nil {
		panic(err)
	}
	fileInfo, _ := open.Stat()
	data := make([]byte, fileInfo.Size())
	_, err = open.Read(data)
	if err != nil {
		panic(err)
	}
	p, _ := pem.Decode(data)
	key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
	if err != nil {
		panic(err)
	}
	hashed := sha256.Sum256(plainText)
	v15, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:])
	if err != nil {
		panic(err)
	}
	return v15
}

func main() {
	fmt.Println(RsaSign([]byte("abc")))
}

公钥验签:

package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

func RsaSign(plainText []byte) []byte {
	open, err := os.Open("private.pem")
	if err != nil {
		panic(err)
	}
	fileInfo, _ := open.Stat()
	data := make([]byte, fileInfo.Size())
	_, err = open.Read(data)
	if err != nil {
		panic(err)
	}
	p, _ := pem.Decode(data)
	key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
	if err != nil {
		panic(err)
	}
	hashed := sha256.Sum256(plainText)
	v15, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, hashed[:])
	if err != nil {
		panic(err)
	}
	return v15
}

func VerifySign(plainText []byte, signature []byte) error {
	open, err := os.Open("public.pem")
	if err != nil {
		panic(err)
	}
	fileInfo, _ := open.Stat()
	data := make([]byte, fileInfo.Size())
	_, err = open.Read(data)
	if err != nil {
		panic(err)
	}
	p, _ := pem.Decode(data)
	key, err := x509.ParsePKIXPublicKey(p.Bytes)
	if err != nil {
		panic(err)
	}

	hashed := sha256.Sum256(plainText)

	return rsa.VerifyPKCS1v15(key.(*rsa.PublicKey), crypto.SHA256, hashed[:], signature)
}

func main() {
	signature := RsaSign([]byte("abc"))
	if err := VerifySign([]byte("abc"), signature); err != nil {
		fmt.Println("验签失败")
		return
	}
	fmt.Println("验签通过")
}

image.png

加解密

这里使用公钥加密数据,私钥解密数据
公钥加密:

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

func Encrypt(plainText []byte) ([]byte, error) {
	open, err := os.Open("public.pem")
	if err != nil {
		panic(err)
	}
	fileInfo, _ := open.Stat()
	data := make([]byte, fileInfo.Size())
	_, err = open.Read(data)
	if err != nil {
		return nil, err
	}
	p, _ := pem.Decode(data)
	key, err := x509.ParsePKIXPublicKey(p.Bytes)
	if err != nil {
		return nil, err
	}
	return rsa.EncryptPKCS1v15(rand.Reader, key.(*rsa.PublicKey), plainText)
}

func main() {
	fmt.Println(Encrypt([]byte("abc")))
}

image.png
私钥解密:

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "os"
)

func Decrypt(plainText []byte) ([]byte, error) {
    open, err := os.Open("private.pem")
    if err != nil {
        panic(err)
    }
    fileInfo, _ := open.Stat()
    data := make([]byte, fileInfo.Size())
    _, err = open.Read(data)
    if err != nil {
        return nil, err
    }
    p, _ := pem.Decode(data)
    key, err := x509.ParsePKCS1PrivateKey(p.Bytes)
    if err != nil {
        return nil,err
    }
    return rsa.DecryptPKCS1v15(rand.Reader, key, plainText)
}

func Encrypt(plainText []byte) ([]byte, error) {
    open, err := os.Open("public.pem")
    if err != nil {
        panic(err)
    }
    fileInfo, _ := open.Stat()
    data := make([]byte, fileInfo.Size())
    _, err = open.Read(data)
    if err != nil {
        return nil, err
    }
    p, _ := pem.Decode(data)
    key, err := x509.ParsePKIXPublicKey(p.Bytes)
    if err != nil {
        return nil, err
    }
    return rsa.EncryptPKCS1v15(rand.Reader, key.(*rsa.PublicKey), plainText)
}

func main() {
    encryptData, _ := Encrypt([]byte("abc"))
    decryptData, _ := Decrypt(encryptData)
    fmt.Println(string(decryptData))
}

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值