非对称加密及案例

2023-10-27

1. 概述

对称加密算法在加密和解密时使用的是同一个密钥,为了解决信息公开传送和密钥管理的问题,于是提出了一种新的密钥交换协议,这种协议允许在不安全的媒体上的通讯双方交换信息、安全地达成一致的密钥系统,这就是非对称加密(公钥加密)。之所以称为非对称加密,是因为使用非对称加密算法时,加密和解密使用的是不同的密钥。这两个密钥分别是私钥(private key)和公钥(public key)。

常用的非对称加密算法有:RSA、ECC

2. 特点

  • 使用公钥加密后,只有对应的私钥才能解密
  • 使用私钥加密后,只有对应的公钥才能机密
  • 算法强度高,不适合加密较大的数据
  • 数据传输的安全性高于对称加密算法

3. RSA

RSA是一种非对称加密算法,它的名字是由它的三位开发者,即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Leonard)。RSA的密钥长度推荐为1024位。

RSA的基本原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

3.1 加密流程

RSA的加密可以用下面这个公式来表示:

密文 = 明文^E mod N

RSA的加密就是对明文代表数字的E次方取模。其中E和N就是RSA加密的密钥,E和N组合就是公钥了。那么如何确定E和N呢?

N的求法:准备两个很大的质数P、Q,然后将这两个数相乘,其结果就是N。N = P * Q

E的求法:首先计算N的欧拉函数(小于N的正整数中与N互质的数的数目)得到L,L = (P-1) * (Q-1),然后在1和L之间选取一个和L互质的数,这个数就是E。

最后就可以得到公钥KU = (E, N)。

3.2 解密流程

RSA的解密可以用下面这个公式来表示:

明文 = 密文^D mod N

RSA的解密就是对密文代表数字的D次方进行取模。这里使用的数字N和加密时使用的N是相同的。所以只有求出D就可以得到私钥。数D和数N组合起来就是解密的密钥,也就是私钥。

D的求法:E对于L的模反元素就是D。可以用这个公式快速求得D:E * D mod L = 1。

最后可以得到私钥KR = (D, N)

3.3 生成公私钥案例

  1. 选择一堆不相等且足够大的质数:P = 3、Q = 11
  2. 计算P和Q的乘积N:N = P * Q = 33
  3. 根据定理计算N的欧拉函数L:L = (P - 1) * (Q - 1) = 20
  4. 从1到L中选取一个与L互质的整数E:1 < E < 10,选取E = 3
  5. 计算E对于L的模反元素D:E * D mod L = 1,D = 7
  6. 求得公钥为:KU = (E, N) = (3, 33)
  7. 求得私钥为:KR = (D, N) = (7, 33)

3.4 使用案例

3.4.1 生成公私钥

// 生成公私钥
func GenerateKeyPair(bits int) {
	// 生成私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		fmt.Println("generate private key err: ", err)
		return
	}

	// 通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
	privateKeyDer := x509.MarshalPKCS1PrivateKey(privateKey)

	// 将私钥字符串设置到pem格式块中
	block := pem.Block{
		Type:    "PRIVATE KEY",
		Headers: nil,
		Bytes:   privateKeyDer,
	}

	// 写入文件
	file1, err := os.Create(privateKeyFile)
	if err != nil {
		fmt.Println("open file err: ", err)
		return
	}
	defer file1.Close()
	// 开始写入	
	err = pem.Encode(file1, &block)
	if err != nil {
		fmt.Println("pem encode err: ", err)
		return
	}

	// 从得到的私钥对象中将公钥信息取出
	publicKey := privateKey.PublicKey
	// 通过x509标准将得到的rsa公钥序列化为字符串
	publicKeyDer := x509.MarshalPKCS1PublicKey(&publicKey)
	// 将公钥字符串设置到pem格式块中
	block2 := pem.Block{
		Type:    "PUBLIC KEY",
		Headers: nil,
		Bytes:   publicKeyDer,
	}
	// 写入文件
	file2, err := os.Create(publicKeyFile)
	if err != nil {
		fmt.Println("open file err: ", err)
		return
	}
	err = pem.Encode(file2, &block2)
	if err != nil {
		fmt.Println("write public key err: ", err)
		return
	}
}

3.4.2 公钥加密

// 公钥加密
ffunc PublicKeyEncrypt(publicKeyFile string, plainText []byte) []byte {
	// 读取私钥
	publicKeyPem, err := ioutil.ReadFile(publicKeyFile)
	if err != nil {
		fmt.Println("read public key file err: ", err)
		return []byte{}
	}

	// 解码成x509格式,rest是未解码完的数据存储在这里
	block, _ := pem.Decode(publicKeyPem)
	// 得到私钥
	publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
	if err != nil {
		fmt.Println("x509 parse public key err: ", err)
		return nil
	}

	// 加密
	cipherData, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
	if err != nil {
		fmt.Println("public encrypt err: ", err)
		return nil
	}

	return cipherData
}

3.4.3 私钥解密

func PrivateKeyDecrypt(privateKeyFile string, cipherData []byte) []byte {
	// 读取私钥
	privateKeyPem, err := ioutil.ReadFile(privateKeyFile)
	if err != nil {
		fmt.Println("read private file err: ", err)
		return nil
	}

	// 从数据中查找到DER格式的块
	privateKeyDer, _ := pem.Decode(privateKeyPem)

	// 解析一个pem格式的私钥
	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyDer.Bytes)
	if err != nil {
		fmt.Println("parse private key err: ", err)
		return nil
	}

	// 解密
	plaintData, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherData)
	if err != nil {
		fmt.Println("private key decrypt err: ", err)
		return nil
	}

	return plaintData
}

测试结果:
在这里插入图片描述

完整代码:https://github.com/bigzoro/cryptography/tree/main/asymmetricalCryption/rsa

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

非对称加密及案例 的相关文章

  • 数字后端——电源规划

    电源规划是给整个芯片的供电设计出一个均勻的网络 它是芯片物理设计中非常关键的一部分 电源规划在芯片布图规划后或在布图规划过程中交叉完成 它贯穿于整个设计中 需要在芯片设计的不同阶段对电源的供电网络进行分析并根据要求进行修改 主要分三部分内容
  • linux 文件夹卡死,目录中文件过多导致ls命令卡住

    你一定遇到过这种情况 在一个有几百万文件的目录中执行ls命令 ls就卡在那了 是吧 用ls 1 f命令可以立即显示出文件 如果你想删除当前目录中的所有文件 使用如下命令 ls 1 f xargs rm 在清理大量不需要的文件后 会留下一个巨

随机推荐

  • 解决redisTemplate存入redis出现乱码问题

    package com example config import org springframework beans factory annotation Autowired import org springframework cont
  • GPT-2解读(论文 + TensorFlow实现)

    GPT 2是对GPT的一个升级 并且更着重于将思路放在为何pretrain是有用的上面 认为LM本身是一个Multi task Learner 并且大力用ZSL实验来佐证这个思路 文章目录 一 前言 二 GPT 2原理 1 数据集 2 输入
  • 用python发带附件的邮件_用Python实现一个简单的能够发送带附件的邮件程序的教程...

    基本思路就是 使用MIMEMultipart来标示这个邮件是多个部分组成的 然后attach各个部分 如果是附件 则add header加入附件的声明 在python中 MIME的这些对象的继承关系如下 MIMEBase MIMENonMu
  • 解决阿里云、华为云等云数据库 Redis 版无法外网访问的问题(云主机搭桥—亲测有效)

    在阿里云 华为云上 购买了一个云数据库Redis 但是我通过本地的客户端或者程序 没法通过公网访问 不造为啥会有这样约定俗成的 华为云更是有意思 你如果想要开启公网访问 你需要额外购买弹性公网IP 一 云数据库Redis版问题 比如说我在华
  • 【OpenGL开发】VS2017+nuget配置OpenGL开发环境

    文章目录 1 简介 1 1 先决条件 1 2 查找并安装包 1 3 卸载软件包 1 4 更新包 1 5 管理解决方案的包 1 6 合并 选项卡 2 nuget配置程序源 2 1 在线源 2 2 本地源 3 nuget安装库 3 1 nuge
  • Unity MRTK-UI 的常见基件的简单介绍以及使用

    目录 MRTK UI 的初步使用 色彩色调的选用 MRTK UI交互基本模块的使用 BUTTON SLATE Slider MRTK UI 的初步使用 色彩色调的选用 在实际的设计使用中 考虑对用户的视觉友好性 我们避免使用透明度过高的以及
  • java安装配置以及eclipse下载(Windows10)

    1安装java 安装java有两部 1 安装jdk和jre 2 配置环境 1 1 安装jdk 和 jre jdk 安装网址 http www oracle com technetwork java javase downloads inde
  • 使用NIST库查找介质衰减系数

    前提 本文需要利用NIST库查找物质X射线下的衰减系数 NIST库网址 https www nist gov pml 进入网址后显示如下界面 点击左侧选项栏 点开后选择 向下拉选择 选择 而后滑到底部 根据需要选择对应的表格
  • JVM问答

    目录 1 什么是Java虚拟机 为什么Java被称作是 平台无关的编程语言 2 Java内存结构 3 解释内存中的栈 stack 堆 heap 和方法区 method area 的用法 4 对象分配规则 5 什么是类的加载 6 类加载器 7
  • Mycat读写分离、主从切换学习

    Mycat读写分离 主从切换学习 2016 02 21 21 39 01来源 CSDN作者 zhanglei 16155人点击 id iframeu2217703 0 src http pos baidu com pcum rdid 221
  • PyMacroParser 宏解析工具

    PyMacroParser 宏解析工具 PyMarcoParser宏解析工具 题目要求 题目描述 示例 解题思路 1 load函数 2 preDefine函数 3 dumpDict函数 4 dump函数 关键代码 1 主要函数 2 关键函数
  • 每日一题:蒟蒻

    蒟蒻 题目 Daimayuan Online Judge map可以一一映射 按键值从小到大排序 AC代码 include
  • 多线程大串讲之一:CreateThread的学习

    function CreateThread lpThreadAttributes Pointer 安全设置 dwStackSize DWORD 堆栈大小 lpStartAddress TFNThreadStartRoutine 入口函数 l
  • unity 编辑模式下运行代码和OnEnable的使用

    AudioListener inspector的代码运行 inspector页面的脚本右上角三个小点 点击右键 选择自己写的函数名 就可以运行 相应的程序了 重点 ContextMenu SetPos ContextMenu SetPos
  • 总结一下使用过的几类LCD屏特点

    1 MCU屏 一般MCU屏都会自带显存 接口为16位的80并口 相当于支持RGB565模式 8080是通过 读使能 RE 和 写使能 WE 两条控制线进行读写操作 关键管脚说明 RESET脚 复位LCD RS 寄存器选择 置1为写数据 置0
  • ios播放gif图片

    以前一直听说ios不可以播放gif图片 也没取看看 其实想想有啥不能播放的 只是没有提供现成的api而已 最近看看资料以及别人的例子了解了一下实现原理 特记录一下 gif 其实本来就是一系列的图片的集合 可以通过 imageIO 获取到图片
  • 如何配置 vscode 识别@文件路径

    在前端开发项目中常常会使用 别名 但是在vscode中默认是不识别的 可以使用下面的配置让vscode 识别 文件路径 以便支持 ctrl 左键 点击跳转 方式一 项目配置 在项目根目录创建 jsconfig json 文件 文件内容 co
  • 一文讲清数据集市、数据湖、数据网格、数据编织

    本文介绍数据仓库 数据集市 数据湖 数据网格和数据编织相关概念和使用案例 帮助你选择并利用好数据的力量来完成明智的决策 微信搜索关注 Java学研大本营 在今天的数字时代 企业每天都在应对来自四面八方的海量数据 随着对强大的数据管理和分析需
  • 基于51单片机的无线防盗报警器

    硬件设计 无线多路防盗报警器由l台接收机和多台发射机组成 接收机可以接收多台发射机 其频率都是一样的 只是编码脉冲不同 发来的报警信号 并且加以区别 进行译码然后以数字显示的形式将这些台发射机识别出来 同时音响报警 多路无线防盗报警器主要是
  • 非对称加密及案例

    1 概述 对称加密算法在加密和解密时使用的是同一个密钥 为了解决信息公开传送和密钥管理的问题 于是提出了一种新的密钥交换协议 这种协议允许在不安全的媒体上的通讯双方交换信息 安全地达成一致的密钥系统 这就是非对称加密 公钥加密 之所以称为非