RSA算法Java版(不要求支持大数)但实现了(dog

2023-11-09

RSA算法(支持大数)

题目描述

C++中数据的类型与长度参考:

因此,C++最大能支持的十进制是19位的整数。如果要支持更大的整数,需要实现Big Number类。RSA目前比较安全的密钥长度是2048位二进制,即是617位的十进制。因此,C++自带的数据类型无法实现安全的RSA密钥加解密。

为了降低难度,该题不要求实现大数支持,因此只使用C++自带的long long 数据类型。

该实验主要包含三部分:

1. 公私钥的生成。

在公私钥生成中,有p、q、e三个参数是随机选择的,其中p、q要求是质数,因此需要实现一个函数检查一个整数是否是质数。由p、q的乘积可以得到n:n=pq,以及n的欧拉函数: φ(n) = (p-1)(q-1)。e是在(1, φ(n))之间随机选取的整数,需要满足gcd(e, φ(n)) = 1,因此,需要通过扩展欧几里得算法验证取得的e是与φ(n)互质的。d可以通过扩展欧几里得算法求得 。以满足
在这里插入图片描述
在这里插入图片描述

公钥为(n, e),私钥为(n,d)

检查一个整数是否为质数-Rabin-Miller算法,请参考:

https://blog.csdn.net/ECNU_LZJ/article/details/72675595

https://www.cnblogs.com/zwfymqz/p/8150969.html

https://www.cnblogs.com/zwfymqz/p/8150861.html

扩展欧几里得算法:请参考:

https://blog.csdn.net/u014117943/article/details/108428551

2.加密过程,使用加密算法c = m^e mod n,计算出密文c;

3.解密过程,使用私钥d和解密算法m = c^d mod n, ,计算m;

加密和解密过程需要做幂运算取余,如果直接先做幂运算再取余,则很容易出现溢出,因此,我们需要采用快速幂运算取余算法,请参考:https://jlice.top/p/7tbs7/

因此,该次实验主要难点在于以下三个算法的理解与实现:

  1. Rabin-Miller算法

  2. 扩展欧几里得算法

  3. 快速幂取余算法

根据前面的算法,我们知道明文和密文都不能大于n,假设n的长度为L,对于明文,我们需要按照L-1的长度对其分组然后再加密,每组的密文长度L。解密的时候使用L的长度对其进行分组然后解密,每组的明文长度为L-1。分组按照整数从低到高(即从右往左)

输入

第一行是p

第二行是q

第三行是e

第四行是待加密数据

第五行是待解密数据

输出

第一行输出p是否是质数

第二行输出q是否是质数

第三行打印n

第四行打印d

第五行显示输入第四行的加密结果

第六行显示输入第五行的解密结果

输入样例1

67
43
13
281
2154

输出样例1

Yes
Yes
2881
853
325
54

输入样例2

67
43
13
54281
3252154

输出样例2

Yes
Yes
2881
853
21540325
281054

输入样例3

11
17
7
88
11

输出样例3

Yes
Yes
187
23
11
88

前置条件

虽然题目没要求大数,但是现在不用以后也会遇到这种问题,就顺便学了一下Java.BigInteger类的常用API

求和:
BigInteger add(BigInteger val) 返回两个大整数的和
求差:
BigInteger subtract(BigInteger val) 返回两个大整数的差
求积:
BigInteger multiply(BigInteger val) 返回两个大整数的积
求商:
BigInteger divide(BigInteger val) 返回两个大整数的商
求模:
BigInteger mod(BigInteger val) 用当前大整数对val求模
求乘方:
BigInteger pow(int exponent) 返回当前大整数的exponent次方
求余:
BigInteger remainder(BigInteger val) 返回当前大整数除以val的余数
类型转换:
double doubleValue() 返回大整数的double类型的值
float floatValue() 返回大整数的float类型的值
long longValue() 返回大整数的long型值
int intValue() 返回大整数的整型值
其它:
BigInteger abs() 返回大整数的绝对值
BigInteger gcd(BigInteger val) 返回大整数的最大公约数
BigInteger max(BigInteger val) 返回两个大整数的最大者
BigInteger min(BigInteger val) 返回两个大整数的最小者
byte[] toByteArray(BigInteger val)将大整数转换成二进制反码保存在byte数组中

此外还有String和BigInteger的相互转化

public class test {
    public static void main(String[] args){
        String a = "1234567890123456789";
        //String转为BigInteger
        BigInteger b=new BigInteger(a);
        //BigInteger转为String
        String c = String.valueOf(b);
        System.out.println("b:"+b);
        System.out.println("c:"+c);
    }
}

判断素数还有比较大小…

.isProbablePrime(int certainty):如果该 BigInteger 可能是素数,则返回 true ;如果它很明确是一个合数,则返回 false 。 参数 certainty 是对调用者愿意忍受的不确定性的度量:如果该数是素数的概率超过了 1 - 1/2*certainty方法,则该方法返回 true 。执行时间正比于参数确定性的值。

AC代码

import java.math.BigInteger;
import java.util.Scanner;


/**
 * RSA算法(不要求支持大数)
 *
 * @author xzx
 * @date 2022/11/22
 */
public class Main {


    private static BigInteger x = BigInteger.ZERO;
    private static BigInteger y = BigInteger.ZERO;

    public static void main(String[] args) {
        // parse input arguments
        Scanner scanner = new Scanner(System.in);
        BigInteger p = scanner.nextBigInteger();
        BigInteger q = scanner.nextBigInteger();
        BigInteger e = scanner.nextBigInteger();
        BigInteger plainNumber = scanner.nextBigInteger();
        BigInteger encryptedNumber = scanner.nextBigInteger();
        System.out.println(isPrime(p) ? "Yes" : "No");
        System.out.println(isPrime(q) ? "Yes" : "No");

        BigInteger n = getN(p, q);

        // P 与 Q 均为质数 φ(n) = φ(P*Q)= (P-1)(Q-1)
        BigInteger mod = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
        System.out.println(n);
        if (exgcd(e, mod).equals(BigInteger.ONE)) {
            if (x.compareTo(BigInteger.ZERO) == -1) x = x.add(mod);
            System.out.println(x);
        }
        // 根据前面的算法,我们知道明文和密文都不能大于n,假设n的长度为L
        int L = n.toString().length();
        // 对于明文,我们需要按照【L-1的长度对其分组然后再加密,每组的密文长度L】。
        System.out.println(encrypt(plainNumber, n, e, L, L - 1));
        // 解密的时候使用【L的长度对其进行分组然后解密,每组的明文长度为L-1】
        System.out.println(decrypt(encryptedNumber, n, x, L - 1, L));

    }

    /**
     * 扩展欧几里得算法 ax+by=gcd(a,b)
     *
     * @param a
     * @param b
     * @return
     */
    private static BigInteger exgcd(BigInteger a, BigInteger b) {
        if (b.equals(BigInteger.ZERO)) {
            x = BigInteger.ONE;
            y = BigInteger.ZERO;
            return a;  //到达递归边界开始向上一层返回
        }
        BigInteger r = exgcd(b, a.mod(b));
        BigInteger temp = y;    //把x y变成上一层的
        y = x.subtract(a.divide(b).multiply(y));
        x = temp;
        return r;     //得到a b的最大公因数
    }

    /**
     * 解密过程,使用私钥d和解密算法m = c^d mod n
     *
     * @param c      密文
     * @param n
     * @param d
     * @param L      分组长度
     * @param length 明文长度
     * @return
     */
    private static BigInteger decrypt(BigInteger c, BigInteger n, BigInteger d, int L, int length) {
        return encrypt(c, n, d, L, length);
    }

    /**
     * 加密过程,使用加密算法c = m^e mod n,计算出密文c
     *
     * @param m      明文
     * @param n
     * @param e
     * @param L      算法前对数字分组的长度
     * @param length 算法后结果的长度(即存在补'0'操作)
     * @return
     */
    private static BigInteger encrypt(BigInteger m, BigInteger n, BigInteger e, int L, int length) {
        // m < n
        if (m.compareTo(n) != 1) {
            return powMod(m, e, n);
        }
        // 分组按照整数从低到高(即从右往左)
        String mStr = m.toString();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = mStr.length(); i - length > -length; i -= length) {
            // 分组从左到右,长度为length
            String batchM = mStr.substring(Math.max(0, i - length), i);
            // 计算
            StringBuilder subStr = new StringBuilder(powMod(new BigInteger(batchM), e, n).toString());
            // 补足'0'
            while (subStr.length() < L) {
                subStr.insert(0, "0");
            }
            // 头插
            stringBuilder.insert(0, subStr);
        }
        return new BigInteger(stringBuilder.toString());
    }


    /**
     * 快速幂取余算法
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    private static BigInteger powMod(BigInteger a, BigInteger b, BigInteger c) {
        BigInteger result = BigInteger.ONE;
        while (!b.equals(BigInteger.ZERO)) {
            if (b.mod(BigInteger.valueOf(2)).equals(BigInteger.ONE)) {
                result = result.multiply(a).mod(c);
            }
            b = b.divide(BigInteger.valueOf(2));
            a = a.multiply(a).mod(c);
        }
        return result;
    }

    /**
     * p * q
     *
     * @param p
     * @param q
     * @return
     */
    private static BigInteger getN(BigInteger p, BigInteger q) {
        return p.multiply(q);
    }

    /**
     * 检查一个整数是否是质数
     *
     * @param number
     * @return
     */
    static boolean isPrime(BigInteger number) {
        return number.isProbablePrime(1);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RSA算法Java版(不要求支持大数)但实现了(dog 的相关文章

  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • hibernate 6.0.2.Final 和 spring boot 2.7.0 的entityManagerFactory bean 未配置问题

    所以最近我想升级我的 Spring Boot 项目项目的一些依赖项 特别是这些组件 雅加达 EE 9 弹簧靴2 7 休眠 6 0 2 Final 完成此操作后 所有更新和代码折射 更新将 javax 导入到 jakarta 以及一些 hib
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • partitioningBy 必须生成一个包含 true 和 false 条目的映射吗?

    The 分区依据 https docs oracle com javase 8 docs api java util stream Collectors html partitioningBy java util function Pred
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • Log4j2 ThreadContext 映射不适用于parallelStream()

    我有以下示例代码 public class Test static System setProperty isThreadContextMapInheritable true private static final Logger LOGG
  • Android View Canvas onDraw 未执行

    我目前正在开发一个自定义视图 它在画布上绘制一些图块 这些图块是从多个文件加载的 并将在需要时加载 它们将由 AsyncTask 加载 如果它们已经加载 它们只会被绘制在画布上 这工作正常 如果加载了这些图片 AsyncTask 就会触发v
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • 将 char[][] 转换为 char** 会导致段错误吗?

    好吧 我的 C 有点生疏了 但我想我应该用 C 来做我的下一个 小 项目 这样我就可以对其进行抛光 并且我已经有不到 20 行的段错误了 这是我的完整代码 define ROWS 4 define COLS 4 char main map
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐

  • 序列化错误小结:SerializationFailedException

    公司项目 不提供具体代码 仅提供思路 问题描述 错误报告MultipartRequest无法实现序列化 问题解决1 发生SerializationFailedException时 第一时间根据错误报告定位错误类 发现MultipartReq
  • 分布式事务专题之9、分布式事务解决方案之最大努力通知型

    目录 1 支付宝充值案例 假如我们自己有一个电商系统 支持用户使用支付宝充值 流程如下 2 用户支付流程 是一个同步的过程 用户在浏览器发起充值请求 gt 电商服务 电商服务生成充值订单 状态为0 待支付 0 待支付 100 支付成功 20
  • 软件产品质量模型

    ISO IEC 9126是国际标准组织 ISO 制订的用于评估软件质量的国际标准1 ISO IEC 9126标准由6个特性和27个子特性组成 是评价软件质量的国际标准1 ISO IEC 9126已经被ISO IEC 25010取代 后者是国
  • STM32刷Micropython固件参考指南

    STM32刷Micropython固件指南 其实刷固件和普通的程序下载烧录无多大的差异 主要是其他因数的影响导致刷固件或刷完固件无法运行的情况和相关问题 刷固件教程 固件下载 目前所支持的stm32型号有这些 stm32f0 stm32f4
  • linux进阶05——Makefile(二)

    1 源代码 main c int main printf hello world n fun1 fun2 fun1 c void fun1 printf this is fun1 n fun2 c void fun2 printf this
  • BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding

    BERT 个人翻译 并不权威 paper https arxiv org pdf 1810 04805 pdf BERT Pre training of Deep Bidirectional Transformers for Languag
  • sql语句大全+实例讲解

    1 创建3张表 学生表创建 CREATE table student Sno CHAR 9 PRIMARY KEY Sname CHAR 20 UNIQUE Ssex char 2 Sage SMALLINT Sdept char 20 课
  • LCD 驱动

    LCD的型号是 CM162 4 有U1 U2 外形尺寸 L W H mm 80 36 12 点数 mm 5 8 内藏控制器 SPLC 780 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 GND VDD VO
  • vue3+element-plus+js 对列表查询/重置条件 组件简单封装

    在写后台管理的时候会有很多列表 列表上面一般会有查询条件 对列表进行搜索查询 所以就想封装成为组件 就不需要每个页面写一堆的代码 直接循环出来进行遍历即可 1 封装子组件searchForm组件
  • 利用Bat命令批量修改文件名

    因为科研需求 需要把文件名规范统一命名 整体思路 先获得原始文件名字 带后缀 再导到excel里搞好新名字 构建好Bat的ren函数 完成修改 具体措施 1 读取原本文件名称 在相应的文件目录下 新建一个文本文件 并且打开输入 dir b
  • 移动端物理像素和设备独立像素

    https blog csdn net aiolos1111 article details 51880223 https www cnblogs com samwu p 5341056 html http www softwhy com
  • ifconfig命令详解

    在CU论坛里看到一个关于google面试的帖子 当中提到的一个面试题就是ifconfig命令的用法 所以今天就趁些机会在网上找了一些关于ifconfig的文章 转到这边来 大家一起学习 以下转自 http www photox cn IT
  • linux之date命令

    date 命令用于 显示 或 设置系统的时间或日期 格式 date 参数 日期格式 注意 date后面有一个空格 否则无法识别命令 shell对空格是很严格的 1 Linux date命令参数 日期时间格式符号 H 小时 以00 23来表示
  • x = torch.cat((x1, x2), dim=1) dim是什么意思,决定什么变量

    在这个例子中 x torch cat x1 x2 dim 1 意思是将 x1 和 x2 按照第一维拼接起来 得到新的 tensor x 变量 dim 1 决定了拼接的维度
  • re学习(29)攻防世界-CatFly(复原反汇编)

    因为这是一个 dll文件 在Linux上运行一下 找到主要函数 以及由上面三部分对应的代码部分 int64 fastcall main int a1 char a2 char a3 size t v3 rbx int16 v5 4 rsp
  • Docker安装Elasticsearch 8.x 、Kibana 8.x等

    这里我使用的是8 2 0版本 同时内容会介绍ik分词和elastic head的安装 elasticsearch java的配置 1 下载ik分词器插件 下载地址 https github com medcl elasticsearch a
  • 年轻人 vs 存款

    近日 有调查称 大概五分之一的年轻人存款在一万元以内 10万元存款是一个 坎 存款超过10万就会超过53 7 的人 年轻人 存款 两个词碰撞在一起 引来了广泛的关注和讨论 你认为年轻人存款难吗 可以从以下几个角度发表你的看法 存款 角度一
  • Redis入门之一

    设置后台进程 进入redis conf中的136行改成 yes 设置后台进程 修改bind 改成qianfeng01 改密码 找到第500行左右 requorepass 改成123456 登录的代码 查看 ps ef grep redis
  • 数据挖掘基础之数据库

    最近出现的一种数据库结构是数据仓库 1 3 2 小节 这是一种多个异种数据源在单个站点以统一的模式组织的存储 以支持管理决策 数据仓库 技术包括数据清理 数据集成和联机分析处理 OLAP OLAP 是一种分析技术 具有汇总 合并和聚集功能
  • RSA算法Java版(不要求支持大数)但实现了(dog

    RSA算法 支持大数 题目描述 C 中数据的类型与长度参考 因此 C 最大能支持的十进制是19位的整数 如果要支持更大的整数 需要实现Big Number类 RSA目前比较安全的密钥长度是2048位二进制 即是617位的十进制 因此 C 自