golang生成RSA公钥和密钥的实现方法

 更新时间:2024年08月14日 10:12:32   作者:幸享龙枫  
本文主要介绍了golang生成RSA公钥和密钥的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

场景

场景一:加密、解密

A服务器向B服务器传入一组请求参数,这组参数比较敏感,所以需要A进行加密;

B接收到参数,因是加密过的,所以需要用特定的方式进行解密。

场景二:微信退款

微信退款功能,对接过的小伙伴都知道,微信官方会生成一组密钥、公钥文件给到我们

场景三:SSL证书

例如我们使用nginx部署HTTPS时,就需要用到SSL证书,去购买了证书后,就能得到SSL证书文件,由两个文件组成:.key 和 .pem 格式的文件,而这两个文件,就是rsa公钥和私钥

为什么是.key和.pem格式的文件

RSA生成的公钥和私钥保存为.key和.pem格式的文件,主要是出于可读性和安全性的考虑。

可读性:

  • RSA公钥和私钥的原始数据通常是二进制格式,对于人类来说直接阅读和理解这些二进制数据是非常困难的。
  • 为了提高可读性,这些二进制数据通常会被转换为Base64编码的文本格式。Base64编码是一种用64个可打印字符来表示二进制数据的方法,它可以将二进制数据转换为ASCII字符串格式,从而便于人类阅读和理解
  • PEM(Privacy Enhanced Mail)格式就是基于Base64编码的文本格式,用于表示和传输密钥、证书等加密数据。PEM文件通常以"-----BEGIN...-----"和"-----END...-----"作为文件的开头和结尾,中间是Base64编码的数据。

安全性:

  • PEM格式不仅可以表示公钥和私钥的Base64编码数据,还可以包含其他信息,如加密算法、证书链等。这些信息对于密钥和证书的管理和使用非常重要。
  • PEM文件通常使用文本文件的形式存储,这使得它们可以在不同的操作系统和平台之间轻松交换和传输。同时,由于PEM文件是文本格式,所以可以使用文本编辑器或专门的工具进行查看和编辑,这有助于用户更好地管理和使用密钥和证书。
  • 需要注意的是,虽然PEM文件提高了密钥和证书的可读性和可管理型,但这也带来了一定的安全风险。因为PEM文件可以被任何人读取和复制,所以必须采取适当的安全措施来保护PEM文件的安全性和完整性。例如,可以将PEM文件存储在受保护的目录中,并限制对文件的访问权限;或者使用加密的方式存储和传输PEM文件等。

文件扩展名:

  • .key和.pem是常见的文件扩展名,用于表示不同类型的密钥和证书文件。虽然它们都可以用于存储RSA公钥和私钥的Base64编码数据,但具体的选择可能取决于特定的应用场景或工具的要求。
  • 一般来说,.key文件可能更多地用于表示私钥文件,而.pem文件则可能用于表示公钥,私钥或证书文件。然后,这并不是一个严格的规定,所以具体的选择可能因实际情况而异。

综上所述,RSA生成的公钥和私钥保存为.key和.pem格式的文件,主要是为了提高数据的可读性和安全性,并方便用户在不同的操作系统和平台之间交换和使用这些密钥和证书。

生成密钥、公钥

接下来,我们使用 golang 敲敲代码生成密钥和公钥

package main

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

func main() {
	GenerateRsa()
}

// GenerateRsa 生成rsa
func GenerateRsa() {
	// 生成RSA密钥对
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		log.Fatalf("Error generating key: %s", err)
	}
	fmt.Println(privateKey) // 打印密钥
	publicKey := &privateKey.PublicKey
	fmt.Println(publicKey) // 打印公钥
}

执行命令:

go run main.go

打印了下面:

这些也就是我们所说的:

"RSA公钥和私钥的原始数据通常是二进制格式,对于人类来说直接阅读和理解这些二进制数据是非常困难的"

密钥、公钥保存到文件中

现在,我们将已生成的公钥、私钥,保存到文件里,而文件格式分别是.key和.pem

.key 保存私钥

.pen 保存公钥

我封装了两个方法:

第一个:保存密钥到文件里

// SavePrivateKey 将私钥保存到PEM格式的文件中
func SavePrivateKey(privateKey *rsa.PrivateKey, dirPath string, fileName string) error {
	_, err := os.Stat(dirPath) // 获取目录文件信息
	// 如果目录不存在
	if err != nil || os.IsNotExist(err) {
		// 递归的创建目录
		err := os.MkdirAll(dirPath, 0755)
		if err != nil {
			return fmt.Errorf("Error creating directory: %s\n", err)
		}
	}
	// 将私钥编码为ASN.1 DER格式
	privateKeyDER := x509.MarshalPKCS1PrivateKey(privateKey)

	// 使用PEM格式包装DER数据
	block := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: privateKeyDER,
	}

	// 将PEM块写入文件
	filePath := fmt.Sprintf("%s/%s", dirPath, fileName)
	file, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = pem.Encode(file, block)
	if err != nil {
		return err
	}

	return nil
}

第二个:保存公钥到文件里

// SavePublicKey 将公钥保存到PEM格式的文件中
func SavePublicKey(publicKey *rsa.PublicKey, dirPath string, fileName string) error {
	_, err := os.Stat(dirPath) // 获取目录文件信息
	// 如果目录不存在
	if err != nil || os.IsNotExist(err) {
		// 递归的创建目录
		err := os.MkdirAll(dirPath, 0755)
		if err != nil {
			return fmt.Errorf("Error creating directory: %s\n", err)
		}
	}
	publicKeyASN1, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		return err
	}

	// 使用PEM格式包装DER数据
	block := &pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: publicKeyASN1,
	}

	// 将PEM块写入文件
	filePath := fmt.Sprintf("%s/%s", dirPath, fileName)
	file, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = pem.Encode(file, block)
	if err != nil {
		return err
	}

	return nil
}

因为在 main 主函数里,我们调用了 "GenerateRsa" 函数,所以我们在 "GenerateRsa" 里调用这两个方法:

// GenerateRsa 生成rsa
func GenerateRsa() {
	// 生成RSA密钥对
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		log.Fatalf("Error generating key: %s", err)
	}
	publicKey := &privateKey.PublicKey
	dirPath := "/app/rsa"
	fileName := "private.key"
	err = SavePrivateKey(privateKey, dirPath, fileName)
	if err != nil {
		fmt.Println(err)
	}
	fileName = "public.pem"
	err = SavePublicKey(publicKey, dirPath, fileName)
	if err != nil {
		fmt.Println(err)
	}
}

因为 main 主函数里,调用了 "GenerateRsa()",所以我们直接运行go程序

go run main.go

运行后,因为我们没有额外的打印信息,也没有出现报错信息,所以我们可以看一下目录下:

/app/rsa

在这个目录下,就生成了以下两个文件:

private.key
public.pem

到此这篇关于golang生成RSA公钥和密钥的实现方法的文章就介绍到这了,更多相关golang生成RSA公钥和密钥内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • golang struct 实现 interface的方法

    golang struct 实现 interface的方法

    这篇文章主要介绍了golang struct 实现 interface的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • 浅谈Go语言的error类型

    浅谈Go语言的error类型

    这篇文章主要介绍了浅谈Go语言的error类型,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • GO语言gin框架实现管理员认证登陆接口

    GO语言gin框架实现管理员认证登陆接口

    这篇文章主要介绍了GO语言gin框架实现管理员认证登陆接口,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • golang实现unicode转换为字符串string的方法

    golang实现unicode转换为字符串string的方法

    这篇文章主要介绍了golang实现unicode转换为字符串string的方法,实例分析了Go语言编码转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • 浅谈go语言中别名类型的使用

    浅谈go语言中别名类型的使用

    类型别名是 Go 1.9 版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题,本文主要介绍了go语言中别名类型的使用,感兴趣的可以了解一下
    2024-01-01
  • Golang实现AES对称加密算法实例详解

    Golang实现AES对称加密算法实例详解

    所谓对称加密是指在加密和解码时使用同一密钥的加密方式,下面这篇文章主要给大家介绍了关于Golang实现AES对称加密算法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • 一文详解Golang中net/http包的实现原理

    一文详解Golang中net/http包的实现原理

    这篇文章主要介绍了如何用 net/http 自己编写实现一个 HTTP Server 并探究其实现原理,具体讲解Go语言是如何接收和处理请求的,希望能够对大家的学习或工作具有一定的帮助
    2022-08-08
  • 详解Golang net/http包中的RoundTripper接口

    详解Golang net/http包中的RoundTripper接口

    RoundTripper 是 net/http 包中的一个接口,定义了处理 HTTP 请求返回和响应的方法,是 http.Client 结构体中执行 http 请求的核心部分,本文将详细的给大家介绍Golang RoundTripper接口,需要的朋友可以参考下
    2023-09-09
  • Go语言中Seeker接口的用法详解

    Go语言中Seeker接口的用法详解

    Go语言标准库中的io包提供了一系列接口,用于处理各种I/O操作,其中Seeker接口在处理大文件或需要随机访问的场景中非常有用,本文将结合具体案例,详细介绍Go语言中io包的Seeker接口的用法,需要的朋友可以参考下
    2024-10-10
  • golang waitgroup辅助并发控制使用场景和方法解析

    golang waitgroup辅助并发控制使用场景和方法解析

    Golang 提供了简洁的 go 关键字来让开发者更容易的进行并发编程,同时也提供了 WaitGroup 对象来辅助并发控制,今天我们就来分析下 WaitGroup 的使用方法,顺便瞧一瞧它的底层源码
    2023-09-09

最新评论