常用加密算法go实现

密码学

加密算法

加密算法分类:对称加密算法、非对称加密算法和杂凑算法(散列函数)

  • 对称加密算法:DES、3DES(重复三次DES过程)、AES、SM4

​ - 常用加密模式:ECB、CBC、CFB、OFB、CRT等 参考

  • 非对称加密算法:RSA、DSA、SM2、ECDSA(椭圆加密)

​ 非对称加密算法根据加密所使用的密钥不同,可分为加密(用公钥加密私钥解密)和数字签名(私钥加密公钥解密)

  • 杂凑算法:MD5、SHA-1系列、SHA-2系列、SM3

​ 杂凑算法又称为散列算法,不同算法得到定长的散列值。介绍

对称加密算法

DES

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/hex"
	"fmt"
)

//使用DES加密
//src 待加密明文 , key 密钥

//加密
func EncryptDES(src, key []byte) []byte {
	//创建cipher.Block接口 其对应的就是一个加密块
	block, err := des.NewCipher(key)
	if nil != err {
		panic(err)
	}
	length := block.BlockSize()
	//填充最后一组数据
	src = PaddingText(src, length)
	//初始化向量
	iv := []byte("12345678")
	//创建cbc加密模式
	blockMode := cipher.NewCBCEncrypter(block, iv)
	//创建切片,用于存储加密后的数据
	dst := make([]byte, len(src))
	blockMode.CryptBlocks(dst, src)
	return dst
}

//解密

func DecryptDES(src, key []byte) []byte {
	//创建解密块
	block, err := des.NewCipher(key)
	if nil != err {
		panic(err)
	}
	iv := []byte("12345678")
	//创建cbc解密模式
	blockMode := cipher.NewCBCDecrypter(block, iv)
	dst := make([]byte, len(src))
	blockMode.CryptBlocks(dst, src)
	return UnPaddingText(dst)
}

func main() {
	src := []byte("你好!XXX")
	key := []byte("87654321")
	encryptedMsg := EncryptDES(src, key)
	fmt.Println("加密后:", hex.EncodeToString(encryptedMsg))
	decryptedMsg := DecryptDES(encryptedMsg, key)
	fmt.Println("解密后的明文:", string(decryptedMsg))

}

//给最后一组数据填充至64字节
func PaddingText(src []byte, blockSize int) []byte {
	//求出最后一个分组需要填充的字节数
	padding := blockSize - len(src)%blockSize
	//创建新的切片,切片字节数为padding
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	//将新创建的切片和带填充的数据进行拼接
	nextText := append(src, padText...)
	return nextText

}

//取出数据尾部填充的赘余字符

func UnPaddingText(src []byte) []byte {
	//获取待处理数据长度
	len := len(src)
	//取出最后一个字符
	num := int(src[len-1])
	newText := src[:len-num]
	return newText
}

3DES

import (
	"bytes"
	"crypto/cipher"
	"crypto/des"
	"encoding/hex"
	"fmt"
)

func Encrypt3DES(src, key []byte) []byte {
	//创建加密区块
	block, err := des.NewTripleDESCipher(key)
	if nil != err {
		panic(err)
	}
	//填充数据
	src = PaddingText(src, block.BlockSize())

	//加密
	blockmode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
	dst := make([]byte, len(src))
	blockmode.CryptBlocks(dst, src)
	return dst
}

func Decrypt3DES(dst, key []byte) []byte {
	//创建解密块
	block, err := des.NewTripleDESCipher(key)
	if nil != err {
		panic(err)
	}
	//创建解密模式
	blockmode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
	src := make([]byte, len(dst))
	blockmode.CryptBlocks(src, dst)
	//去除填充的数据
	src = UnPaddingText(src)
	return src
}

func main() {
	encrypt_msg := []byte("你好 XXX")
	key := []byte("123456788765432112345678")
	encrypted3DES_msg := Encrypt3DES(encrypt_msg, key)
	fmt.Println(hex.EncodeToString(encrypted3DES_msg))

	decrypt_msg := Decrypt3DES(encrypted3DES_msg, key)
	fmt.Println(string(decrypt_msg))
}

//给最后一组数据填充至64字节
func PaddingText(src []byte, blockSize int) []byte {
	//求出最后一个分组需要填充的字节数
	padding := blockSize - len(src)%blockSize
	//创建新的切片,切片字节数为padding
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	//将新创建的切片和带填充的数据进行拼接
	nextText := append(src, padText...)
	return nextText

}

//取出数据尾部填充的赘余字符

func UnPaddingText(src []byte) []byte {
	//获取待处理数据长度
	len := len(src)
	//取出最后一个字符
	num := int(src[len-1])
	newText := src[:len-num]
	return newText
}

AES

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/hex"
	"fmt"
)

func EncryptAES(src, key []byte) []byte {
	block, err := aes.NewCipher(key)
	if nil != err {
		panic(err)
	}
	//填充
	src = PaddingText(src, block.BlockSize())
	//初始化向量
	iv := []byte("12345678abcdefgh")
	//创建加密模式
	blockmode := cipher.NewCBCEncrypter(block, iv)
	dst := make([]byte, len(src))
	//加密
	blockmode.CryptBlocks(dst, src)
	return dst
}

func DecryptAES(src, key []byte) []byte {
	block, err := aes.NewCipher(key)
	if nil != err {
		panic(err)
	}
	//初始化向量
	iv := []byte("12345678abcdefgh")
	blockmode := cipher.NewCBCDecrypter(block, iv)
	//解密
	dst := make([]byte, len(src))
	blockmode.CryptBlocks(dst, src)
	//去除填充
	dst = UnPaddingText(dst)
	return dst
}

func main() {
	src := []byte("你好!潘丽萍")
	key := []byte("8765432112345678")
	encryptedMsg := EncryptAES(src, key)
	fmt.Println("加密后:", hex.EncodeToString(encryptedMsg))
	decryptedMsg := DecryptAES(encryptedMsg, key)
	fmt.Println("解密后的明文:", string(decryptedMsg))
}

//给最后一组数据填充至64字节
func PaddingText(src []byte, blockSize int) []byte {
	//求出最后一个分组需要填充的字节数
	padding := blockSize - len(src)%blockSize
	//创建新的切片,切片字节数为padding
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	//将新创建的切片和带填充的数据进行拼接
	nextText := append(src, padText...)
	return nextText

}

//取出数据尾部填充的赘余字符

func UnPaddingText(src []byte) []byte {
	//获取待处理数据长度
	len := len(src)
	//取出最后一个字符
	num := int(src[len-1])
	newText := src[:len-num]
	return newText
}

SM4

import (
	"bytes"
	"crypto/cipher"
	"encoding/hex"
	"fmt"

	"github.com/tjfoc/gmsm/sm4"
)

func EncryptSM4(src, pwd []byte) []byte {
	//创建加密块
	block, err := sm4.NewCipher([]byte(pwd))
	if nil != err {
		panic(err)
	}
	//填充数据
	src = PaddingText(src, block.BlockSize())
	//初始化向量
	iv := []byte("1234567887654321")
	//设置加密模式
	blockmode := cipher.NewCBCEncrypter(block, iv)
	dst := make([]byte, len(src))
	blockmode.CryptBlocks(dst, src)
	return dst
}

func DecryptSM4(src, pwd []byte) []byte {
	//创建解密块
	block, err := sm4.NewCipher(pwd)
	if nil != err {
		panic(err)
	}
	//初始化向量
	iv := []byte("1234567887654321")
	//创建解密模式
	blockmode := cipher.NewCBCDecrypter(block, iv)
	dst := make([]byte, len(src))
	//解密
	blockmode.CryptBlocks(dst, src)

	//去除填充
	dst = UnPaddingText(dst)
	return dst
}

func main() {
	msg := []byte("你好!XXX")
	pwd := []byte("1234567887654321")
	encryptedMsg := EncryptSM4(msg, pwd)
	decryptMsg := DecryptSM4(encryptedMsg, pwd)
	fmt.Printf("%v\n%v", hex.EncodeToString(encryptedMsg), string(decryptMsg))
}

//给最后一组数据填充至64字节
func PaddingText(src []byte, blockSize int) []byte {
	//求出最后一个分组需要填充的字节数
	padding := blockSize - len(src)%blockSize
	//创建新的切片,切片字节数为padding
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	//将新创建的切片和带填充的数据进行拼接
	nextText := append(src, padText...)
	return nextText

}

//取出数据尾部填充的赘余字符

func UnPaddingText(src []byte) []byte {
	//获取待处理数据长度
	len := len(src)
	//取出最后一个字符
	num := int(src[len-1])
	newText := src[:len-num]
	return newText
}

非对称加密算法

DSA

import (
	"crypto/dsa"
	"crypto/rand"
	"fmt"
	"math/big"
)

//对消息进行加密生成数字签名
func GenDSA() (*dsa.PrivateKey, *dsa.PublicKey) {
	//生成私钥所需要的参数
	var para dsa.Parameters
	//GenerateParameters的第三个参数决定L、N的长度,长度越长加密程度越高
	dsa.GenerateParameters(&para, rand.Reader, dsa.L1024N160)
	//将初始化好的参数传入给私钥
	var priKey dsa.PrivateKey
	priKey.Parameters = para
	dsa.GenerateKey(&priKey, rand.Reader)
	return &priKey, &priKey.PublicKey
}

//验证数字签名
func EncryptDSA(priKey *dsa.PrivateKey, src []byte) (r, s *big.Int) {
	r, s, err := dsa.Sign(rand.Reader, priKey, src)
	if nil != err {
		panic(err)
	}
	return r, s
}

//验证数字签名的真实性
func VerifyDSA(pubKey *dsa.PublicKey, src []byte, r, s *big.Int) bool {
	return dsa.Verify(pubKey, src, r, s)
}

//对消息本身进行签名
func main() {
	priKey, publicKey := GenDSA()
	msg := []byte("你好! XXX")
	r, s := EncryptDSA(priKey, msg)
	verifyDSA := VerifyDSA(publicKey, msg, r, s)
	if verifyDSA {
		fmt.Println("验证通过!")
	} else {
		fmt.Println("验证失败!")
	}
}

RSA

import (
	"crypto"
	"crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"fmt"
)

//生成密钥对
func GenKey() (*rsa.PrivateKey, *rsa.PublicKey) {
	PriKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if nil != err {
		panic(err)
	}
	return PriKey, &PriKey.PublicKey
}

//用私钥和指定的hash函数对消息的散列值进行加密形成数字签名
func EncryptRSA(priKey *rsa.PrivateKey, src string) []byte {
	//对消息进行hash
	hash := md5.New()
	hash.Write([]byte(src))
	bytes := hash.Sum(nil)
	//对散列值进行加密
	opt := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: crypto.MD5}
	sig, err := rsa.SignPSS(rand.Reader, priKey, crypto.MD5, bytes, opt)
	if nil != err {
		panic(err)
	}
	return sig
}

//验证数字签名的真实性
func VerifyRSA(pubKey *rsa.PublicKey, src string, sig []byte) bool {
	//对消息进行散列处理
	hash := md5.New()
	hash.Write([]byte(src))
	bytes := hash.Sum(nil)
	//对数字签名进行验证
	opt := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: crypto.MD5}
	err := rsa.VerifyPSS(pubKey, crypto.MD5, bytes, sig, opt)
	if nil != err {
		fmt.Println(err)
		return false
	} else {
		return true
	}
}

//rsa对消息的散列值进行数字签名和验证
func main() {
	priKey, publicKey := GenKey()
	sig := EncryptRSA(priKey, "你好!XXX")
	verifyRSA := VerifyRSA(publicKey, "你好!XXX", sig)
	if verifyRSA {
		fmt.Println("验证通过!")
	} else {
		fmt.Println("验证失败!")
	}
}

SM2

import (
	"crypto/rand"
	"fmt"

	"github.com/tjfoc/gmsm/sm2"
)

//生成密钥对
func GenKeyPair() (*sm2.PrivateKey, *sm2.PublicKey) {
	privateKey, err := sm2.GenerateKey(rand.Reader)
	if nil != err {
		panic(err)
	}
	return privateKey, &privateKey.PublicKey
}

//对消息进行加密
func EncryptSM2(pubKey *sm2.PublicKey, src string) []byte {
	sign, err := pubKey.EncryptAsn1([]byte(src), rand.Reader)
	if nil != err {
		panic(err)
	}
	return sign
}

//对消息进行数字签名验证
func VerifySM2(priKey *sm2.PrivateKey, msg string, sign []byte) bool {
	//验证数字签名的正确性
	asn1, err := priKey.DecryptAsn1([]byte(msg))
	if nil != err {
		fmt.Println(err)
		return false
	} else {
		fmt.Println(string(asn1))
		return true
	}

}

func main() {
	msg := "你好!xxx"
	priKey, publicKey := GenKeyPair()
	sign := EncryptSM2(publicKey, msg)
	verifySM2 := VerifySM2(priKey, msg, sign)
	if verifySM2 {
		fmt.Println("验证通过")
	} else {
		fmt.Println("验证失败")
	}
}

ECDSA

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"fmt"
	"math/big"
)

//椭圆加密算法

//生成密钥对
func GenECDSA() (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if nil != err {
		panic(err)
	}
	return privateKey, &privateKey.PublicKey
}
func EncryptECDSA(priKey *ecdsa.PrivateKey, src string) (r, s *big.Int) {
	//对信息进行hash
	bytes := sha256.Sum256([]byte(src))
	//对散列值进行加密
	r, s, err := ecdsa.Sign(rand.Reader, priKey, bytes[:])
	if nil != err {
		panic(err)
	}
	return r, s
}

func VerifyECDSA(pubKey *ecdsa.PublicKey, src string, r, s *big.Int) bool {
	//对消息进行hash
	bytes := sha256.Sum256([]byte(src))
	//验证签名
	return ecdsa.Verify(pubKey, bytes[:], r, s)

}
func main() {
	msg := "你好!XXX"
	priKey, publicKey := GenECDSA()
	r, s := EncryptECDSA(priKey, msg)
	verifyECDSA := VerifyECDSA(publicKey, msg, r, s)
	if verifyECDSA {
		fmt.Println("验证通过")
	} else {
		fmt.Println("验证失败")
	}
}

散列算法

MD5

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"os"
)

//对文件进行hash处理

func HashFileMD5(path string) string {
	//1、获取文件句柄
	file, err := os.Open(path)
	if nil != err {
		panic(err)
	}
	//2、将文件内容写入到hash
	hash := md5.New()
	_, err = io.Copy(hash, file)
	if nil != err {
		panic(err)
	}
	//3、计算散列值
	bytes := hash.Sum(nil)
	return hex.EncodeToString(bytes)
}
func main() {

	//散列对象创建
	hash := md5.New()
	//将内容写入对象
	hash.Write([]byte("区块链"))
	//计算出散列值
	sum := hash.Sum(nil)
	fmt.Println(hex.EncodeToString(sum))
	//75d8fafb0706c9381d4c91e3b184f19d

	hash.Reset()
	hash.Write([]byte("区块链"))
	bytes := hash.Sum([]byte("123"))
	fmt.Println(hex.EncodeToString(bytes))
	//313233  75d8fafb0706c9381d4c91e3b184f19d
	i := md5.Sum([]byte("区块链"))
	fmt.Println(hex.EncodeToString(i[:]))
	fileMD5 := HashFileMD5("privateKey.pem")
	fmt.Println(fileMD5, "-------3234")
}

SHA-256

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
)

func main() {
	hash := sha256.New()
	hash.Write([]byte("你好!XXX"))
	bytes := hash.Sum(nil)
	fmt.Println(hex.EncodeToString(bytes))
	//36eda9afdaae39041fcbd101618717330a07b188373ab21f28e87e8793a7014d
}

SM3

import (
	"encoding/hex"
	"fmt"

	"github.com/tjfoc/gmsm/sm3"
)

func EncryptSM3(msg string) string {
	hash := sm3.New()
	hash.Write([]byte(msg))
	bytes := hash.Sum(nil)
	return hex.EncodeToString(bytes)
}
func main() {
	encryptSM3 := EncryptSM3("你好!XXX")
	fmt.Println(encryptSM3)
	sm3Sum := sm3.Sm3Sum([]byte("你好!XXX"))
	fmt.Println(hex.EncodeToString(sm3Sum))
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值