Go-RSA加密解密详解与代码_go rsa

encoding/pem包

crypto/x509包

crypto/rsa包

生成RSA密钥对

加解密

截图

参考


对称密码的缺点

保密通信进入计算机网络时代,传统密码体制逐渐暴露其固有的弱点,体现在密钥分发。通过前面的对称密码文章,可以看到需要双方知道密钥。问题在于我要给你发送秘密信息,没有安全的通道,发送信息前需要找到安全的通道告诉你密钥,然后再在不安全通道进行通信。问题是我既然找到了安全的通道,直接发送消息不就行了吗? 当然,古代大部分是在线下约定好的,类似《悬崖之上》的密码本。

对称密码解决了密钥分发问题,可以在不安全通道发送密钥。当然,对称密码还有数字签名问题,后面数字签名相关的文章再说。

RSA概述

W.Diffie和Hellman发表了著名的文章《密码学的新方向》首次提出了公钥密码算法的思想。

公钥密码体制为密码学的发展提供了新的理论和技术思想,一方面公钥密码算法是建立在数学函数基础上的,而不是建立在字符或位方式的操作上的;另一方面公钥密码算法是以非对称的形式使用加密密钥和解密密钥,这两个密钥的使用对密钥管理、认证等都有着深刻的实际意义。可以说,公钥密码体制的出现在密码学发展史上是一次质的飞跃。

1978年,Rivest,Shamir和Adleman提出的RSA算法体现了公钥算法的思想,被认为是第一个安全的、实用的公钥密码算法。

RSA的理论基础是数论的**欧拉定理,它的安全性依赖于大整数的素因子**分解的困难性。

RSA密钥对生成算法

  1. 选取两个大素数p和q,两个数长度接近且相差较大。
  2. 计算n=p*q,9(n)=(p-1)(q-1)。
  3. 随机选取整数e,满足gcd(ee(n))=1。
  4. 计算d,满足d*e=1(mode(n))。

注:p和q保密。e和n为公钥,d为私钥。

RSA加解密过程

加密算法:c=E(m)=m^e(mod n)

解密算法:m=D©=c^d(mod n)

RSA小结

  • 第一个实用的公开密钥算法。
  • 目前使用最多的一种公钥密码算法。
  • RSA的理论基础是数论的欧拉定理
  • RSA的安全性依赖于大数的素因子分解的困难性。
  • 密码分析者既不能证明也不能否定RSA的安全性。
  • 既能用于加密也能用于数字签名
  • 目前密钥长度1024位是安全的。

RSA的Go实现

encoding/pem包

func Decode(data []byte) (p *Block, rest []byte)

Decode函数会从输入里查找到下一个PEM格式的块(证书、私钥等)。它返回解码得到的Block和剩余未解码的数据。如果未发现PEM数据,返回(nil, data)。

crypto/x509包

func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte

MarshalPKCS1PrivateKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码。

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

MarshalPKIXPublicKey将公钥序列化为PKIX格式DER编码。

func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)

ParsePKIXPublicKey解析一个DER编码的公钥。这些公钥一般在以"BEGIN PUBLIC KEY"出现的PEM块中。

func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)

ParsePKCS1PrivateKey解析ASN.1 PKCS#1 DER编码的rsa私钥。

crypto/rsa包

func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error)

EncryptPKCS1v15使用PKCS#1 v1.5规定的填充方案和RSA算法加密msg。信息不能超过((公共模数的长度)-11)字节。注意:使用本函数加密明文(而不是会话密钥)是危险的,请尽量在新协议中使用RSA OAEP。

func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error)

DecryptPKCS1v15使用PKCS#1 v1.5规定的填充方案和RSA算法解密密文。如果random不是nil,函数会注意规避时间侧信道攻击。

生成RSA密钥对

  1. 使用rsa.GenerateKey生成私钥
  2. 使用x509.MarshalPKCS1PrivateKey序列化私钥为derText
  3. 使用pem.Block转为Block
  4. 使用pem.Encode写入文件
  5. 从私钥中获取公钥
  6. 使用x509.MarshalPKIXPublicKey序列化公钥为derStream
  7. 使用pem.Block转为Block
  8. 使用pem.Encode写入文件
func GenerateRsaKey(keySize int, dirPath string) error {
	privateKey,err := rsa.GenerateKey(rand.Reader,keySize)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	// x509
	derText :=x509.MarshalPKCS1PrivateKey(privateKey)
	// pem Block
	block := &pem.Block{
		Type:"rsa private key",
		Bytes:derText,
	}
	// just joint, caller must let dirPath right
	file,err := os.Create(dirPath+"private.pem")
	defer file.Close()
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	err = pem.Encode(file,block)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	// get PublicKey from privateKey
	publicKey := privateKey.PublicKey
	derStream,err := x509.MarshalPKIXPublicKey(&publicKey)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	block = &pem.Block{
		Type:"rsa public key",
		Bytes:derStream,
	}
	file,err = os.Create(dirPath+"public.pem")
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	err = pem.Encode(file, block)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return util.Error(file,line+1,err.Error())
	}
	return nil
}

加解密

加密

  1. 获取公钥
  2. 使用x509.ParsePKIXPublicKey解析公钥
  3. 使用rsa.EncryptPKCS1v15加密
func RsaEncrypt(plainText []byte,filePath string) ([]byte, error) {
	// get pem.Block
	block,err := util.GetKey(filePath)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return nil,util.Error(file,line+1,err.Error())
	}
	// X509
	publicInterface,err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return nil,util.Error(file,line+1,err.Error())
	}
	publicKey,flag := publicInterface.(*rsa.PublicKey)
	if flag == false{
		_, file, line, _ := runtime.Caller(0)
		return nil,util.Error(file,line+1,errors.RsatransError)
	}
	// encrypt
	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
	if err != nil{
		_, file, line, _ := runtime.Caller(0)
		return nil,util.Error(file,line+1,err.Error())
	}
	return cipherText,nil
}

解密

  1. 获取私钥
  2. 使用x509.ParsePKCS1PrivateKey解析私钥
  3. 使用rsa.DecryptPKCS1v15解密

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

8674866)]

[外链图片转存中…(img-tQcCUUig-1715488674866)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值