密码技术--非对称加密算法及Go语言应用

非对称加密算法

1.对称加密的弊端
  • 秘钥分发困难

  • 可以通过非对称加密完成秘钥的分发

    Alice和Bob通信,Alice给Bob发送数据,使用对称加密的流程

    1.Bob生成一个非对称的密钥对,

    2.Bob将公钥发送给Alice

    3.Alice生成一个用于对称加密的秘钥

    4.Alice使用Bob的公钥就对对称加密的秘钥进行加密,并发送给Bob

    5.Bob使用私钥对数据解密,得到对称加密的私钥

    通信的双方使用写好的秘钥进行对称加密对数据加密

  • 场景分析

1.通信流程,信息加密(A写数据给B,信息只允许B读)
A: 公钥
B:私钥

2.登录认证(客户端要登录,连接服务器,向服务器请求个人数据)
客户端:私钥
服务端:公钥

3.数字签名(表明信息没有受到篡改,确实是信息拥有者发出来的,附在信息原文的后面)
发送端:私钥
接受端:公钥

4.网银U盾
个人:私钥
银行:公钥.

总结: 数据对谁更重要,谁就拿私钥

2. 非对称加密的秘钥
  • 不存在秘钥分发的困难问题
3.生成RSA的密钥对
  1. 概念
    x509证书规范、pem、base64

    • pem是一种源自保密增强邮件协议的编码规范,可进行数据加密
    • base64也是一种编码规范,过程可逆
    • 无论原始数据是什么,将原始数据使用64个字符来代替(a-z、A-Z、0-9、/、+)

    ASN.1抽象语法标记
    PKCS1标准

  2. 密钥对生成流程

  • 私钥生成

1.使用rsa中的GenerateKey方法生成私钥
func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)

  • rand.Reader -> import “crypto/rand”
  • bits 1024的整数倍-建议

2.通过x509标准将得到的rsa私钥序列化为ASN.1的DER编码字符串
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte

3.将私钥字符串设置到pem格式块中
初始化一个pem.Block块

4.通过pem将设置好的数据进行编码,并写入磁盘文件
func Encode(out io.Writer, b *Block) error
out - 准备一个文件指针

  • 公钥生成

1.从得到的私钥对象中将公钥信息取出

type PrivateKey struct {
 PublicKey            // 公钥
 D         *big.Int   // 私有的指数
 Primes    []*big.Int // N的素因子,至少有两个
 // 包含预先计算好的值,可在某些情况下加速私钥的操作
 Precomputed PrecomputedValues
}

2.通过x509标准将得到的rsa公钥序列化为字符串

func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)

3.将公钥字符串设置到pem格式块中

4.通过pem将设置好的数据进行编码,并写入磁盘文件

4.RSA加解密
package main

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

//生成rsa私钥和公钥并写入磁盘文件
func GenerateRsaKey(keySize int) {
	//1.生成rsa秘钥
	privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
	if err != nil {
		panic(err)
	}
	//2.通过x509标准将得到的rsa私钥序列化为ASN.1的DER编码字符串
	derText := x509.MarshalPKCS1PrivateKey(privateKey)
	//3.创建一个pem.Block结构体
	block := pem.Block{
		Type: "rsa private key",
		Bytes: derText,
	}
	//4.通过pem将设置好的私钥数据进行编码,并写入磁盘文件
	file, err := os.Create("private.pem")
	if err != nil {
		panic(err)
	}
	err = pem.Encode(file, &block)
	if err != nil {
		panic(err)
	}

	// ==========公钥==================
	//1.从私钥中取出公钥
	publicKey := privateKey.PublicKey
	//2.使用x509序列化公钥为字符串
	marshalPKIXPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
	if err != nil {
		panic(err)
	}
	//3.通过公钥字符串设置到pem格式块中
	block = pem.Block{
		Type:    "rsa public key",
		Headers: nil,
		Bytes:   marshalPKIXPublicKey,
	}
	//4.pem编码
	file, err = os.Create("public.pem")
	if err != nil {
		panic(err)
	}
	err = pem.Encode(file, &block)
	if err != nil {
		panic(err)
	}
	file.Close()
}

//rsa加密
func RSAEncrypt(plainText []byte, fileName string) []byte {
	//1.打开公钥文件
	file, err := os.Open(fileName)
	if err != nil {
		panic(err)
	}
	fileInfo, err := file.Stat()
	if err != nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		panic(err)
	}
	file.Close()
	//2.pem decode
	block, _ := pem.Decode(buf)
	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	pubKey := publicKey.(*rsa.PublicKey)
	//3.使用公钥加密
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, plainText)
	if err != nil {
		panic(err)
	}
	return cipherText
}

//rsa解密
func RSADecrypt(cipherText []byte, fileName string) []byte {
	//1.打开私钥文件
	file, err := os.Open(fileName)
	if err != nil {
		panic(err)
	}
	fileInfo, err := file.Stat()
	if err != nil {
		panic(err)
	}
	buf := make([]byte, fileInfo.Size())
	_, err = file.Read(buf)
	if err != nil {
		panic(err)
	}
	//2.pem decode
	block, _ := pem.Decode(buf)
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	//3.解密数据
	plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
	if err != nil {
		panic(err)
	}
	return plainText
}

func main() {
	GenerateRsaKey(1024)
	src := []byte("解决了秘钥分发的困难问题,不能加密稍长一点的数据,主要用来加密对称秘钥")
	cipherText := RSAEncrypt(src, "public.pem")
	plainText := RSADecrypt(cipherText, "private.pem")
	fmt.Println("解密结果:", string(plainText))
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值