前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分享几个 Go 语言中使用 RSA 算法对字符串的加密解密的代码片段

分享几个 Go 语言中使用 RSA 算法对字符串的加密解密的代码片段

作者头像
耕耘实录
发布2023-12-19 09:29:42
2210
发布2023-12-19 09:29:42
举报
文章被收录于专栏:耕耘实录耕耘实录

一 生成公钥和私钥

使用随机数据生成器random生成一对具有指定字位数的RSA密钥,生成 RSA 的公钥和私钥,并保存至 key 目录中,入参为加密的位数。

代码语言:javascript
复制
// GenerateRSAKey 函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥,生成 RSA 的公钥和私钥,并保存至 key 目录中,入参为加密的位数。
func GenerateRSAKeys(bits int) {
	if createDir("keys") {
		fmt.Println("keys目录已成功新建,本次生成的公钥和私钥将存放于该目录,请谨慎保存!")
	} else {
		fmt.Println("keys目录已存在,本次生成的公钥和私钥将存放于该目录,请谨慎保存!")
	}
	//Reader是一个全局、共享的密码用强随机数生成器
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		panic(err)
	}
	//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串,使用pem格式对x509输出的内容进行编码。
	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
	//创建文件保存私钥
	privateFile, err := os.Create("keys/private.key")
	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)
	}
	//创建用于保存公钥的文件
	publicFile, err := os.Create("keys/public.key")
	if err != nil {
		panic(err)
	}
	defer publicFile.Close()
	//创建一个pem.Block结构体对象
	publicBlock := pem.Block{Type: "PUBLIC KEY", Bytes: X509PublicKey}
	pem.Encode(publicFile, &publicBlock)
}

二 从私钥推导出公钥

传入字符串类型的私钥,返回其对应的公钥。并将对应的公钥和私钥存放到相应的目录。

代码语言:javascript
复制
func GetPublicKeyFromPrivateKey(privateKeyString string) string {
	privateKeyBytes := []byte(privateKeyString)
	privateKeyBlock, _ := pem.Decode(privateKeyBytes)
	if privateKeyBlock == nil || privateKeyBlock.Type != "RSA PRIVATE KEY" {
		panic(errors.New("解码包含公钥的PEM块失败"))
	}
	publicKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
	if err != nil {
		panic(err)
	}
	publicKeyDer, _ := x509.MarshalPKIXPublicKey(&publicKey.PublicKey)
	publicKeyBlock := pem.Block{Type: "PUBLIC KEY", Bytes: publicKeyDer}
	return string(pem.EncodeToMemory(&publicKeyBlock))
}
// createDir 创建存放公钥和私钥的目录,如已经存在则不创建.
func createDir(name string) bool {
	_, err := os.Stat(name)
	if !os.IsExist(err) {
		e := os.Mkdir("keys", os.ModePerm)
		if e != nil {
			return false
		}
	} else {
		return false
	}
	return true
}

三 使用公钥对字符串进行加密

公钥加密方法,第一个参数为需要加密的字符串,第二个参数为 RSA 公钥字符串。加密后返回一个 Base64 编码的字符串及错误。

代码语言:javascript
复制
func PublicKeyEncrypt(text string, publicKey string) (string, error) {
	var publicKeyBytes []byte = []byte(publicKey)
	block, _ := pem.Decode(publicKeyBytes)
	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	// 类型断言
	pubKey := publicKeyInterface.(*rsa.PublicKey)

	// 对明文进行加密
	encryptText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, []byte(text))
	if err != nil {
		panic(err)
	}
	// 返回base64编码字符串
	return base64.StdEncoding.EncodeToString(encryptText), nil
}

四 使用私钥对已加密的字符串进行解密

私钥解密方法,第一个参数为base64编码的加密字符串,第二个参数为 RSA 私钥字符串。解密后返回原始字符串。

代码语言:javascript
复制
func PrivateKeyDecrypt(encryptText string, privateKey string) (string, error) {
	decryptTextBytes, err := base64.StdEncoding.DecodeString(encryptText)
	if err != nil {
		panic(err)
	}
	block, _ := pem.Decode([]byte(privateKey))
	//X509解码
	priKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	//对密文进行解密
	decryptText, _ := rsa.DecryptPKCS1v15(rand.Reader, priKey, decryptTextBytes)
	//返回明文
	return string(decryptText), nil
}

以上内容仅供参考。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 生成公钥和私钥
  • 二 从私钥推导出公钥
  • 三 使用公钥对字符串进行加密
  • 四 使用私钥对已加密的字符串进行解密
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档