golang生成RSA公钥和密钥

news2024/12/23 4:12:53

目录

场景

场景一:加密、解密

场景二:微信退款

场景三:SSL证书

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

生成密钥、公钥

密钥、公钥保存到文件中

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

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


场景

场景一:加密、解密

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1874434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI产品活跃用户排名出炉!文心一言APP国内第一,Kimi疯狂掉队

AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/ 6月28日,极光大数据旗下月狐数据发布2024年5月中国生成式AI行业市场热点月度分析报告,披露了国内移动端主流生成式AI应用…

一个AI图片生成工具导航网站

上周末上线了一个AI图片生成工具导航网站,主要是面向AI图片工具这个垂直领域。 https://chatgpt-image-generator.com/ 目标是通过收集当下的一些工具,然后进行分类管理,一方面方便大家发现新的工具,另一方面能够更加有针对性、…

操作系统期末复习(对抽象概念的简单形象化)

操作系统 引论 定义与基本概念:操作系统是计算机硬件与用户之间的桥梁,类似于家中的管家,它管理硬件资源(如CPU、内存、硬盘),并为用户提供方便的服务(应用程序执行、文件管理等)。…

Typora 2024 安装教程

本章教程,介绍一下如何使用Typora 最新版本1.9.4,仅供学习交流,切勿滥用。 一、下载安装包 下载地址:https://www.alipan.com/s/8pvKf5ns6GH 当然,你也可以去官网下载,但是官网有可能随时更新,该…

探索CSS布局:创建一个居中的内嵌方块示例

在网页设计中,布局是至关重要的部分。CSS提供了多种方式来实现元素的布局,包括居中对齐、外边距、内边距等。本文将通过一个简单的示例,介绍如何使用CSS来创建一个居中的内嵌方块,并探讨其背后的布局原理。 HTML 结构 首先&…

【Matlab】-- 飞蛾扑火优化算法

文章目录 文章目录 01 飞蛾扑火算法介绍02 飞蛾扑火算法伪代码03 基于Matlab的部分飞蛾扑火MFO算法04 参考文献 01 飞蛾扑火算法介绍 飞蛾扑火算法(Moth-Flame Optimization,MFO)是一种基于自然界飞蛾行为的群体智能优化算法。该算法由 Sey…

上市公司绿色投资者原始数据+计算代码(2008-2022年)

数据简介:“绿色”信号,意味着潜在环境风险更低,从而绿色投资者降低了对绿色债券的风险补偿要求,推动了信用利差的收窄。因此,绿色投资者会通过投资者风险意识影响债券信用风险。绿色投资者在推动企业绿色可持续发展方…

江山欧派杯2024全国华佗五禽戏线上线下观摩交流比赛在亳州开幕

6月28日,2024全国华佗五禽戏线上线下观摩交流比赛在安徽省亳州市开幕。 此次比赛是由安徽省亳州市文化旅游体育局和安徽省非物质文化遗产保护中心主办、亳州市华佗五禽戏协会(国家级非遗华佗五禽戏保护单位)和亳州市传统华佗五禽戏俱乐部&…

GIT版本管理工具轻松入门 | TortoiseGit

目录 一、下载git 二、下载tortoisegit(可视化git) 三、Git本地仓库创建 四、git克隆 五、添加,提交,推送,拉取 六、分支 七、冲突 八、忽略文件(修改gitignore文件) 一、下载git 安装…

关于转BigDecimal对象时,精度问题

//浮点型数值Double d 0.0003d;//转BigDecimal对象BigDecimal a new BigDecimal(d);System.out.println(String.format("浮点类型数字:%.4f创建BigDecimal对象并且保留多位小数并且保留多位小数时,精度会变多,结果为%s",d,a.setScale(8, BigDecimal.ROUND_DOWN)));…

高电压技术-冲击高压发生器MATLAB仿真

微❤关注“电气仔推送”获得资料(专享优惠) 冲击电压发生器是产生冲击电压波的装置,用于检验电力设备耐受大气过电压和操作过电压的绝缘性能,冲击电压发生器能产生标准雷电冲击电压波形,雷电冲击电压截波,标准操作冲击…

Spring底层原理之bean的加载方式三 用注解声明配置类 以及@Configuration 和 @Component 的区别

bean的加载方式三 用注解声明配置类 我们之前用组件扫描加上注解定义bean 实现了bean的加载 当我们又会发现这个配置文件过于繁琐 我们可以写一个类 不是配置文件而是配置类 我们接下来只需要把这句话的功能写到 配置类里面 这样书写就行 package com.bigdata1421.config;…

Git(涵盖GitHub\Gitee码云\GitLab)

Git(涵盖GitHub\Gitee码云\GitLab) 文章目录 Git(涵盖GitHub\Gitee码云\GitLab)课程介绍Git概述官网介绍版本控制介绍两种版本控制工具集中式版本控制工具分布式版本控制工具 Git工作机制代码托管中心 Git安装和客户端的使用Git常用命令设置用户签名初始化本地库查看本地库状态…

软件构造 | Design Patterns for Reuse and Maintainability

Design Patterns for Reuse and Maintainability (面向可复用性和可维护性的设计模式) Open-Closed Principle (OCP) ——对扩展的开放,对修改已有代码的封 Why reusable design patterns A design… …enables flexibility to change …

uni-appx使用form表单页面初始化报错

因为UniFormSubmitEvent的类型时 e-->detail-->value,然后没有了具体值。所以页面初始化的时候 不能直接从value取值,会报错找不到 所以form表单里的数据我们要设置成一个对象来存放 这个问题的关键在于第22行代码 取值: 不能按照点的方式取值 …

如何在Java中使用Levenshtein距离实现字符串相似度匹配

在许多应用中,我们需要根据用户输入的问题找到最匹配的已知问题。Levenshtein距离(编辑距离)是一个强大的工具,可以帮助我们衡量两个字符串之间的差异,并进一步计算它们的相似度。本文将使用一个具体的例子来展示如何在…

BUUCTF-WEB(第二天)

[极客大挑战 2019]Http 这题明显考察的是http协议,打开靶场访问什么也没有,F12来查看看控制台的html源码,直到最后那里我们才看到一个Secret.php文件4,所以直接访问即可。 回显字符串:It doesnt come from https://S…

检索增强生成 (RAG):揭开这一术语的神秘面纱并解释其带来的价值

一、介绍 如今,数据已成为新的黄金,而高效筛选这些丰富信息的能力则是成功企业脱颖而出的关键。Retrieval Augmented Generation(RAG)是创新的标杆,尤其是在知识管理领域。它不再只是为了存储信息,而是为了…

记录处理宏病毒的过程

以下是堂弟个人电脑中毒的处理过程,作为网络安全从业人员,第一次遇到宏病毒,以前只是听过过这种病毒,从未见过。 一、中毒原因 电脑使用人没有安全意识,为了玩游戏,在淘宝买了破解版的游戏,并让…

十二、Yocto集成ROS2 app程序(package)

文章目录 Yocto集成ROS2 app程序1. 添加一个ros2 package应用程序2. 添加bb文件集成app应用程序 Yocto集成ROS2 app程序 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第十二篇文章: 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi…