ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

常用加解密

2022-04-25 12:33:23  阅读:228  来源: 互联网

标签:常用 加密 err nil fmt 加解密 func byte


目录

1.加密种类

1.对称加密算法 :常⽤的算法包括DES、3DES、AES、DESX、Blowfish、RC4、RC5、RC6。推荐⽤AES。
⼆、⾮对称加密算法:常见的⾮对称加密算法:RSA、DSA(数字签名⽤)、ECC(移动设备⽤)、Diffie-Hellman、El Gamal。推荐⽤ECC(椭圆曲线密码编码学)。
三、散列算法(Hash算法---单向加密算法):常见的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-
MD5、HMAC-SHA1。推荐MD5、SHA-1。


对称和非对称区别:
对称加密:加解密密码相同
非对称加密:加解密密码不相同

2.常用对称加密算法

2.1base64

base64特征:结尾可能有"=="号

go

import b64 "encoding/base64"
import "fmt"

func main() {
	data := "123456"
  //加密1
	sEnc := b64.StdEncoding.EncodeToString([]byte(data))
	fmt.Println(sEnc) //MTIzNDU2
  //解密1
	sDec, err := b64.StdEncoding.DecodeString(sEnc)
	if err !=nil{
		fmt.Println(err)
	}
	fmt.Println(string(sDec)) //123456
	

	// 使用兼容URL的base64编码和解码
  //加密2
	uEnc := b64.URLEncoding.EncodeToString([]byte(data))
	fmt.Println(uEnc) //MTIzNDU2
  //解密2
	uDec, _ := b64.URLEncoding.DecodeString(uEnc)
	fmt.Println(string(uDec))//123456
}

python

编码
# 想将字符串转编码成base64,要先将字符串转换成二进制数据
url = "https://www.cnblogs.com/songzhixue/"
bytes_url = url.encode("utf-8")
str_url = base64.b64encode(bytes_url)  # 被编码的参数必须是二进制数据
print(str_url)
b'aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vc29uZ3poaXh1ZS8='

解码
# 将base64解码成字符串
import base64
url = "aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vc29uZ3poaXh1ZS8="
str_url = base64.b64decode(url).decode("utf-8")
print(str_url)

2.2AES

特征:对称加密,加密解密用的是同样的密钥。对称加密是最快速、最简单的一种加密方式
对称加密:适合经常发送数据的场合
非对称加密:加密和解密用的密钥是不同的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。

2.2.1AES的三要素

密钥:128、192、256
填充:
	NoPadding
	PKCS7Padding
	ZeroPadding
	AnsiX923
	lso10126
	lso97971
	
工作模式:
	CBC、ECB、CTR、CFB、OFB

2.2.2AES工作模式区别

工作模式:
	CBC、ECB、CTR、CFB、OFB
ECB模式:
	1、简单
	2、有利于计算
	3、相同的明文块经过加密会变成相同的密文块,因此安全性较差
CBC模式:
	1、无法并行计算,性能上不如ECB
	2、引入初始化向量IV,增加复杂度。
	3、安全性高

2.2.3AES的加密流程

1、把明文按照128bit拆分成若干个明文块
2、按照选择的填充模式来填充最后一个明文块
3、每个明文块利用AES加密器和密钥,加密成密文块

2.2.4AES的特点、特征

1、有iv的是特征的是CBC工作模式
2、mode和padding标示的加密模式、填充方式
iv:初始向量
mode:工作模式
padding:填充方式

2.2.5python的AES

pythonAES加解密

2.2.6go的AES

package main

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

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)]
}

//AES加密,CBC
func AesEncrypt(origData, key []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()
	origData = PKCS7Padding(origData, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // CBC加密
	//blockMode := cipher.NewCFBEncrypter(block,key[:blockSize]) //CFB加密
	crypted := make([]byte, len(origData))
	blockMode.CryptBlocks(crypted, origData)  //CBC加密
	//blockMode.XORKeyStream(crypted,origData) //CFB加密
	crypteBase64:=base64.StdEncoding.EncodeToString(crypted) //返回base64编码
	return crypteBase64, nil
}

//AES解密
func AesDecrypt(crypteBase64 string, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //CBC加密
	//blockMode := cipher.NewCFBDecrypter(block, key[:blockSize]) //CFB加密
	origData := make([]byte, len(crypteBase64))

	crypted,_:= base64.StdEncoding.DecodeString(crypteBase64)

	blockMode.CryptBlocks(origData, crypted) //CBC加密
	//blockMode.XORKeyStream(origData, crypted) //CFB加密
	origData = PKCS7UnPadding(origData)
	return origData, nil
}

func main() {
	text := "123456" // 你要加密的数据
	AesKey := []byte("0123456789123456") // 秘钥,对称秘钥长度必须是16的倍数

	crypteBase64, err := AesEncrypt([]byte(text), AesKey)
	if err != nil {
		panic(err)
	}
	fmt.Println("加密后:",crypteBase64) // KaknGVd4nFWtpiXyZ540SA==


	origin, err := AesDecrypt(crypteBase64, AesKey)
	if err != nil {
		panic(err)
	}
	fmt.Printf("解密后明文: %s\n", string(origin)) //123456
}

3.常用非对称加密算法

3.1RSA加解密

3.1.1生成公钥私钥密钥对

package main

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

//生成RSA私钥和公钥,保存到文件中
// bits 证书大小
func GenerateRSAKey(bits int) {
	//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
	//Reader是一个全局、共享的密码用强随机数生成器
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		panic(err)
	}
	//保存私钥
	//通过x509标准将得到的ras私钥序列化为ASN.1的DER编码字符串
	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
	//使用pem格式对x509输出的内容进行编码
	//创建文件保存私钥
	privateFile, err := os.Create("./go_test/private.pem")
	if err != nil {
		panic(err)
	}
	defer privateFile.Close()
	//构建一个pem.Block结构体对象
	privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
	//将数据保存到文件
	pem.Encode(privateFile, &privateBlock)

	//保存公钥
	//获取公钥的数据
	publicKey := privateKey.PublicKey
	//X509对公钥编码
	X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	if err != nil {
		panic(err)
	}
	//pem格式编码
	//创建用于保存公钥的文件
	publicFile, err := os.Create("./go_test/public.pem")
	if err != nil {
		panic(err)
	}
	defer publicFile.Close()
	//创建一个pem.Block结构体对象
	publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
	//保存到文件
	pem.Encode(publicFile, &publicBlock)
}


func main() {
	//生成密钥对,保存到文件
	GenerateRSAKey(2048)
}

3.1.2RSA

package main

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

//RSA加密
// plainText 要加密的数据
// path 公钥匙文件地址
func RSA_Encrypt(plainText []byte, path string) string {
	//打开文件
	file, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	//读取文件的内容
	info, _ := file.Stat()
	buf := make([]byte, info.Size())
	file.Read(buf)
	//pem解码
	block, _ := pem.Decode(buf)
	//x509解码
	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	//类型断言
	publicKey := publicKeyInterface.(*rsa.PublicKey)
	//对明文进行加密
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
	if err != nil {
		panic(err)
	}
	//返回base编码密文,否则看不懂
	crypteBase64:=base64.StdEncoding.EncodeToString(cipherText) //返回base64编码
	return crypteBase64
}

//RSA解密
// cipherText 需要解密的byte数据
// path 私钥文件路径
func RSA_Decrypt(encryptBase64 string,path string) []byte{
	//打开文件
	file,err:=os.Open(path)
	if err!=nil{
		panic(err)
	}
	defer file.Close()
	//获取文件内容
	info, _ := file.Stat()
	buf:=make([]byte,info.Size())
	file.Read(buf)
	//pem解码
	block, _ := pem.Decode(buf)
	//X509解码
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err!=nil{
		panic(err)
	}
	//base64解码
	cipherText,_:=base64.StdEncoding.DecodeString(encryptBase64)
	//对密文进行解密
	plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey,cipherText)
	//返回明文
	return plainText
}

func main() {
	//加密
	data := []byte("123456") // 原数据
	encryptBase64 := RSA_Encrypt(data, "./go_test/public.pem")
	fmt.Println(encryptBase64)
  //gHudPWYOAPsq7C3RVG/ilykMgKbvqsxQLFhaT9TbdjsM0FDy1odF3AuJkoakLaWMdueigC8UCdQEJhFADh0skPwAonuecqpk3UqljBeDPPgCSPhy2S5nrQMqZuK+EB+fdGnu8ieMmkIQACFQShhnFlqfXbvY5pGi+rjdXTaaXFtxRygtaA+OGHBh7rNWprEainoOC4WeLiHg/v1T6Pk6NiAR3eYjq0L4vadRvkV8MhyjUVifBziW5EXJk00omraoQjAu+1P+PV/wVlFj8BA/4p3ZfMrhzAkTpI/Bewsz5KHJ2xeQg4wEWMrbK8MyHTcH0GRLG+Pk0D/tGawpgW52TA==


	// 解密
	decrypt := RSA_Decrypt(encryptBase64, "./go_test/private.pem")
	fmt.Println(string(decrypt)) //123456
}

3.2ECC加解密

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	//以太坊加密库,要求go版本升级到1.15
	"github.com/ethereum/go-ethereum/crypto/ecies"
)

func genPrivateKey() (*ecies.PrivateKey, error) {
	pubkeyCurve := elliptic.P256() //初始化椭圆曲线
	//随机挑选基点,生成私钥
	p, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader) //用golang标准库生成公私钥
	if err != nil {
		return nil, err
	} else {
		return ecies.ImportECDSA(p), nil //转换成以太坊的公私钥对
	}
}

//ECCEncrypt 椭圆曲线加密
func ECCEncrypt(plain string, pubKey *ecies.PublicKey) ([]byte, error) {
	src := []byte(plain)
	return ecies.Encrypt(rand.Reader, pubKey, src, nil, nil)
}

//ECCDecrypt 椭圆曲线解密
func ECCDecrypt(cipher []byte, prvKey *ecies.PrivateKey) (string, error) {
	if src, err := prvKey.Decrypt(cipher, nil, nil); err != nil {
		return "", err
	} else {
		return string(src), nil
	}
}

func main() {
	prvKey, err := genPrivateKey()
	if err != nil {
		fmt.Println(err)
	}

	pubKey := prvKey.PublicKey
	plain := "123456"
	fmt.Println("原数据:",plain)
	cipher, err := ECCEncrypt(plain, &pubKey)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("密文:",string(cipher))
	plain, err = ECCDecrypt(cipher, prvKey)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("明文:%s\n", plain)
}

4.散列算法

4.1Md5

package main

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

func MD5(str string) string {
	h := md5.New()
	str = str + "加盐"
	h.Write([]byte(str)) // 需要加密的字符串为 123456
	cipherStr := h.Sum(nil)
	return hex.EncodeToString(cipherStr) // 输出加密结
}

func main() {
	data := "123456" //原数据
	md5Data:=MD5(data)
	fmt.Println(md5Data)
}

4.2SHA1

package main

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

func SHA1(s string) string {
	o := sha1.New()
	k := s + "盐"
	o.Write([]byte(k))
	return hex.EncodeToString(o.Sum(nil))

}

func main() {
	data := "123456" //原数据
	hexData := SHA1(data)
	fmt.Println(hexData) //c2adab52abc737ffdb59c31c57b83f88df28e76c
}

标签:常用,加密,err,nil,fmt,加解密,func,byte
来源: https://www.cnblogs.com/guyouyin123/p/16189693.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有