当前位置: 首页 > news >正文

使用C++实现RSA加密解密

一,RSA简介。

RSA,一种非对称加密方式。是目前为止最有影响力的加密算法之一,而且是第一个同时应用于加密和数字签名的算法。

其原理为:两个大素数相乘容易,但是若想将两个大素数相乘的积再分解为两个原始的素数很难。安全性依赖于大数因式分解的困难性。

使用公钥加密,私钥解密。

二,主要原理。

1,公钥私钥的制作过程:

1,选择两个足够大,且互质的素数,p和q。

2,计算出p,q的积,n。

3,计算出n的欧拉函数n1=(p-1)*(q-1).

4,选取公钥e:选择一个与n1互质的质数,不为n1因子且1<e<n1。

5,计算私钥d:d*e mod n1=1(就是e对于n1的模逆元素)。

得到公钥KN(e,n),私钥KR(d,n).

2,加密解密。

设明文为:M;密文为C。

加密:M^e mod n=C。

解密:C^d mod n=M。

三,简单测试。

加密解密

根据第二步中的步骤,我们可以进行一项简单测试。

1,假设p=3,q=11。

2,n为33。

3,n的欧拉函数n1=20。

4,选取公钥:e=3。

5,计算私钥:d*3%20=1,d=7。

得到了公钥KN:(3,33)私钥:KR(7,33)。

假设密文M=15。

加密:15^3mod33=9;C=9。

解密:9^7mod33=15;解密成功。

四,代码实现。

1,难点。

1,素数。

首先要解决的就是判断所输入的数子是否为素数,使用C++实现代码为:

bool isPrime(int num) {// 首先,检查数字0和1不是素数,因为它们只有1个因数if (num <= 1)return false;// 素数大于1,所以我们从2开始遍历到sqrt(num),如果找到能整除num的因子,则num不是素数for (int i = 2; i <= sqrt(num); ++i) {// 如果num可以被i整除,说明num不是素数if (num % i == 0) // 模运算符%,结果为0表示可以整除return false;}// 如果我们没有找到任何因子,那么num就是素数return true;
}

首先,质数不能为负数。

其次在for循环内使用了sqre函数,sqre函数是计算所输入的值的平方根,要判断一个数是不是质数,只需要判断 2到所获取的数字之间开根号有没有可以整除的数就可以了。

此处使用了一个简单的数学规则,假设数n,我们并不知道它是否为质数,虽然也可以使用穷举法,但过于耗费时间;但如果他不是素数,必然存在除了1和它本身之外的数,假设有两个因数,都比根号n大,这两个因数相乘必然比根号n的二次方大,就比n大。所以,如果在2和根号n之间的整数能整除n,就说明n不是质数,反之则为质数。

2,模反因数运算。

在计算模反因数之前,要先了解模运算。

a/b=c……e。

a是被除数,d是除数,c是商,e是余数;在他们当中,e就是模。

简而言之,模就是取余运算,保证c为整数。

基于上述表达式,模运算表示为:

a mod b=e

模反因数的定义为:d*e mod n1=1(就是e对于n1的模逆元素)

就是d*e的积除以n1的值,余数是1。

使用C++实现:

// 函数用于判断一个数是否与n互质
bool isCoprime(int num, int n) {// 如果num和n的最大公约数为1,则它们互质return gcd(num, n) == 1;
}// 函数用于计算两个数的最大公约数
int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);
}// 找到一个最小的与n互质的质数eint e = 2;while (!isPrime(e) || !isCoprime(e, n·1)) {e++;}cout << "找到的最小的与 " << n << " 互质的质数是 " << e << "。" << endl;

2,完整代码。

#include <iostream>
#include <cmath>
using namespace std;// 定义一个函数 isPrime,接收一个整数作为参数
bool isPrime(int num) {// 首先,检查数字0和1不是素数,因为它们只有1个因数if (num <= 1)return false;// 素数大于1,所以我们从2开始遍历到sqrt(num),如果找到能整除num的因子,则num不是素数for (int i = 2; i <= sqrt(num); ++i) {// 如果num可以被i整除,说明num不是素数if (num % i == 0) // 模运算符%,结果为0表示可以整除return false;}// 如果我们没有找到任何因子,那么num就是素数return true;
}
// 找到比 n1 小的最大质数
int findMaxPrimeLessThan(int n1) {for (int i = n1 - 1; i > 1; --i) {if (isPrime(i)) return i;}return -1; // 如果没有找到,返回 -1
}
bool isCoprime(int a, int b) {// 如果num和n的最大公约数为1,则它们互质int gcd(int a, int b);{if (b == 0) {return a;}return gcd(b, a % b);
}
}// 函数用于计算两个数的最大公约数
int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);
}
// 扩展欧几里得算法
void extendedEuclidean(int a, int b, int& x, int& y) {if (b == 0) {x = 1;y = 0;return;}int x1, y1;extendedEuclidean(b, a % b, x1, y1);x = y1;y = x1 - (a / b) * y1;
}// 计算模逆
int modInverse(int a, int m) {int x, y;extendedEuclidean(a, m, x, y);return (x % m + m) % m;
}
// 快速幂算法
long long fastPowerMod(long long base, long long exp, long long mod) {long long result = 1;while (exp > 0) {if (exp % 2 == 1) {result = (result * base) % mod;}base = (base * base) % mod;exp /= 2;}return result;
}int main() {char x;cout << "加密/解密(e/d) :";cin >> x;//输入e或d,e表示加密,d表示解密if (x == 'e' || x == 'E') {char a;cout << "是否使用默认密钥?(y/n) :";cin >> a;//输入y或n,y表示使用默认密钥,n表示使用自定义密钥if (a == 'n'||a == 'N') {cout << "请输入两个用于加密的质数: \n";int num1, num2;cout << "请输入第一个质数: ";cin >> num1;cout << "请输入第二个质数: ";cin >> num2;//输入两个数if (isPrime(num1) && isPrime(num2)) {int p = num1;int q = num2;int n1 = (p - 1) * (q - 1);int e = findMaxPrimeLessThan(n1);//寻找ewhile (!isPrime(e) || !isCoprime(e, n1)) {e++;}int d = modInverse(e, n1);int n = p * q;int C;cout <<"n = "<< n << endl;cout <<"请输入要加密的数字(必须小于n): ";cin >> C;long long M = fastPowerMod(C, e, n);cout << "公钥是 (" << e << ", " << n << "),私钥是 (" << d << ", " << n << ")。" << endl;cout << "加密后的数字是 :" << M << endl;} else {cout << "输入的两个数中至少有一个不是素数,请重新输入。" << endl;}} else {cout << "默认密钥已使用." << endl;int p = 3;int q = 5;int n = p * q;int n1 = (p - 1) * (q - 1);int e = 7;int d = 11;int C;cout <<"n = "<< n << endl;cout <<"请输入要加密的数字(必须小于n): ";cout <<"请输入要加密的数字: ";cin >> C;int M = fmod(pow(C, e), n);cout << "加密前的数字是:" << C << endl;cout << "加密后的数字是:" << M << endl;cout << "公钥是 (" << e << ", " << n << "),私钥是 (" << d << ", " << n << ")。" << endl;}
}else if (x == 'd'||x == 'D') {char a;cout << "是否使用默认密钥?(y/n):";cin >> a;if (a == 'n'||a == 'N'){int d, n, C;cout << "请输入私钥 (d, n),中间使用空格分隔: ";cin >> d >> n;cout << "请输入要解密的数字: ";cin >> C; long long M = fastPowerMod(C, d, n);cout << "解密后的数字是 " << M << endl;}else if (a == 'y'||a == 'Y'){int d = 11;int n = 15;int C;cout <<"请输入要解密的数字: ";cin >> C;int M = fmod(pow(C, d), n);cout << "解密后的数字是 " << M << endl;}else {cout << "输入错误,请重新输入" << endl;}
}
else {cout << "输入错误,请重新输入" << endl;
}return 0;
}

这段代码,或者说这个插件,可以进行RSA计算。不仅可以加密,也可以根据密钥进行解密;而且内置了简单的默认加密方式用于学习,而且还可以对加密参数进行手动修改,更改内容也有相应的检测机制。

运行结果为:

1,使用默认密钥:

2,自定义密钥:

相关文章:

使用C++实现RSA加密解密

一&#xff0c;RSA简介。 RSA&#xff0c;一种非对称加密方式。是目前为止最有影响力的加密算法之一&#xff0c;而且是第一个同时应用于加密和数字签名的算法。 其原理为&#xff1a;两个大素数相乘容易&#xff0c;但是若想将两个大素数相乘的积再分解为两个原始的素数很难…...

C++归并与快速

快排 #include<bits/stdc.h> #include<algorithm> using namespace std; void f(int,int); void cl(int,int,int); void q(int,int); int a[211]; int n; int main(){cin>>n;for(int i0;i<n;i){cin>>a[i];}q(0,n-1);for(int i0;i<n;i){cout<…...

金蝶云苍穹踩过的坑(慢慢更新)

IDEA不能用最新版&#xff0c;不然搜不到金蝶的插件。 我用的是2024.1.7/2023.1.7 IDEA里增加金蝶插件库的地址也变了&#xff0c;现在是 https://tool.kingdee.com/kddt/idea-updatePlugins.xml 金蝶云苍穹部署在服务器 MAC本地IDEA调试的时候&#xff0c;登录N次能成功一次…...

AndroidStudio——安卓项目结构与文件介绍

一、AndroidStudio界面 一个安卓项目界面主要由以下几部分组成&#xff1a; 1.菜单栏&#xff1a;位于顶部&#xff0c;基本的各项菜单操作 2.项目结构&#xff1a;通常位于左侧&#xff0c;展示当前项目的目录结构 3.编辑窗口&#xff1a;通常位于中间&#xff0c;可以用于编…...

华为自反ACL实验

一、实验背景 做这个实验的原因是最近公司里上了三台小程序服务器&#xff0c;由于三台服务器的端口都映射出去了&#xff0c;领导要求A网段的三台服务器不能访问内网B&#xff0c;C网段&#xff0c;同时B、C网段内网用户可以访问A段的94、95、96服务器&#xff1b; 也就是PC4\…...

yml和xml分别代表什么

YML 和 XML 是两种不同的数据序列化格式&#xff0c;它们在软件开发和数据交换中有着广泛的应用&#xff1a; YAML (YAML Ain’t Markup Language): YAML 是一种用于数据序列化的人类可读语言。它被设计为易于阅读和编写&#xff0c;特别适合于配置文件。YAML 使用缩进来表示数…...

Qt多线程编程

在Qt中&#xff0c;多线程编程是一个常见的需求&#xff0c;特别是当你需要执行耗时的后台任务而不希望阻塞用户界面时。多线程编程它允许应用程序同时执行多个任务&#xff0c;从而提高性能和响应速度。Qt提供了一套完善的多线程支持&#xff0c;包括线程类&#xff08;QThrea…...

springboot438校园志愿者管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统校园志愿者管理系统信息管理难度大&#xff0c;容错率低&…...

PostgreSQL 常用运维SQL整理

一、查询并杀会话 -- 查询会话 select pid,usename,client_addr,client_port,query_start,query,wait_event from pg_stat_activity; -- 杀会话 select pg_terminate_backend(pid号); -- 使用如下命令自动生成杀会话语句 select datid,datname,pid,usesysid,usename,applicat…...

Debezium Oracle CTAS 解析器实现:基于 ANTLR 的 CREATE TABLE AS SELECT 语句解析

Debezium Oracle CTAS 解析器实现:基于 ANTLR 的 CREATE TABLE AS SELECT 语句解析 本文详细介绍了 Debezium Oracle 连接器中如何解析 CREATE TABLE AS SELECT (CTAS) 语句,通过具体的实现代码帮助读者理解 ANTLR 监听器在复杂 SQL 解析中的应用。 文章目录 Debezium Oracle…...

从零开始学docker(五)-可用的docker镜像

最近docker镜像都不能访问&#xff0c;目前亲测可用的docker镜像可用&#xff0c;并拉取mysql测试完成。 [缺点] docker search 查不到镜像的索引列表&#xff0c;只能手动查询索引目录&#xff08;解决方案在最后&#xff09;。 linux服务器vim打开镜像文件daemon.json vim /e…...

力扣——322. 零钱兑换

给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...

.Net_比对Json文件是否一致

简介 该方法用于比较两个Json文件是否完全一致&#xff0c;仅考虑内容若两个文件中的内容只是顺序不一致&#xff0c;内容是一样的&#xff0c;那么也代表这两个文件是相等的 实现代码 调用 using CompareJsonFiles;Console.WriteLine(" 输入信息 ");Console.WriteL…...

科研笔记:ARR 与 ACL rolling

1 ARR 介绍 ARR 提供 评审服务 —— 仅限评审 —— 对于提交的论文。评审不会针对特定会议/场所&#xff0c;但评审标准与传统会议的主会场长文或短文提交要求相同&#xff08;如 ACL 或其他由 ACL 主办的重要会议&#xff09; 2 提交论文进行 ARR 评审 提交截止日期 每两个…...

【2024】Camunda常用功能基本详细介绍和使用-上 (1)

这里写目录标题 前言一、 介绍基本概念介绍1.BPMN2.Form3.DMN 二、Camunda使用1、下载安装1.1、camunda-modeler&#xff1a;BPMN绘画工具1.2、camunda-bpm-run&#xff1a;web端控制页面 2、创建流程2.1、部署一个基础流程2.2、添加用户任务2.2.1、绑定表单2.2.1.1、Generated…...

用人话讲计算机:Python篇!(十二)正则运算+re模块

目录 一、正则表达式 &#xff08;1&#xff09;什么是正则表达式 &#xff08;2&#xff09;它的结构及使用 示例&#xff1a; 1.字符 . &#xff08;←这里有个小点哦&#xff09; 2.字符 | 3.字符 [ ] 4.字符^ 5.字符\d &#xff08;3&#xff09;补充&#xff…...

使用create-react-app创建工程时报错处理

1&#xff1a;全局安装create-react-app npm install -g create-react-app 2&#xff1a;切换到项目要创建的目录下 cd /d G:\vsCode_project\react 3&#xff1a;使用脚手架命令创建工程 create-react-app 项目名 项目名命名要遵循npm包命名规范&#xff1a;数字、小写字…...

C# 探险之旅:第三十五节 - 类型class之抽象类 (Abstract Class) 和 抽象方法 (Abstract Method)

&#x1f44b; 嗨&#xff0c;勇敢的探险家们&#xff01;欢迎再次踏上C#的神秘之旅。今天&#xff0c;我们要进入一片既神秘又充满无限可能的领域——抽象类与抽象函数的奇幻森林。想象一下&#xff0c;你是一名勇敢的骑士&#xff0c;要在这片森林里寻找传说中的“编程之宝”…...

qt-C++笔记之父类窗口、父类控件、对象树的关系

qt-C笔记之父类窗口、父类控件、对象树的关系 code review! 参考笔记 1.qt-C笔记之父类窗口、父类控件、对象树的关系 2.qt-C笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理 3.qt-C笔记之自定义类继承自 QObject 与 QWidget 及开发方式…...

Cisco Packet Tarcer配置计网实验笔记

文章目录 概要整体架构流程网络设备互连基础拓扑图拓扑说明配置步骤 RIP/OSPF混合路由拓扑图拓扑说明配置步骤 BGP协议拓扑图拓扑说明配置步骤 ACL访问控制拓扑图拓扑说明配置步骤 HSRP冗余网关拓扑图拓扑说明配置步骤 小结 概要 一些环境配置笔记 整体架构流程 网络设备互连…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...