RSA算法原理及其实现
时间:2019-09-18
本文章向大家介绍RSA算法原理及其实现,主要包括RSA算法原理及其实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1、准备步骤:
1)取8-bit的两个素数(质数)p、q
2)n = p * q,计算 n 的欧拉函数m(表示在小于等于n的正整数之中,与 n 构成互质关系的数的个数),当 p 和 q 均为质数时,m = (p - 1) * (q - 1)
3)随机选取一个整数e,满足条件 1 < e < m 且 e 与 m 互质(但不能选择 m - 1,否则公钥和私钥将相同)
4)找出一个整数 d,使得 e * d mod m = 1,即找出 e 模 m 的逆元(扩展欧几里得算法求逆元,之前的一篇随笔有说明)
5)公钥为(n, e),私钥为(n, d)
2、加密过程
对明文的e次方后除以n求余数,即求:(mingwen)^e mod n
3、解密过程
对密文进行d次方后除以n求余数,即求:(miwen)^d mod n
4、加密及解密实现(对学号+姓名加密):
1 import java.util.ArrayList; 2 3 public class Main { 4 static ArrayList<Integer> suArr = new ArrayList<>(); 5 static int[] xy = new int[2]; 6 7 public static void main(String[] args) { 8 // 由于题目要求取8-bit的两个素数 p,q 因此素数集合的最大值不超过255 9 int max = 255, p = 0, q = 0, n, m, e = -1, index = 0; 10 char[] myInfo = "1700802067GJQ".toCharArray(); 11 int[] miwen = new int[myInfo.length]; 12 char[] mingwen = new char[myInfo.length]; 13 suArr.add(2); 14 15 for (int i = 3; i <= max; i++) { 16 if (isSuShu(i)) 17 suArr.add(i); 18 } 19 20 // 保证取到的两个素数不相等 21 while (p == q) { 22 p = getRanNum(suArr.size()); 23 q = getRanNum(suArr.size()); 24 } 25 26 n = p * q; 27 m = (p - 1) * (q - 1); 28 29 // 求得公钥为(n, e) 30 for (int i = 2; i < m; i++) { 31 if (isHuZhi(m, i) == 1) { 32 e = i; 33 break; 34 } 35 } 36 37 if (e != -1) { 38 exGcd(e, m); 39 /* 40 根据要求(e*d)%m=1求得的d(即xy[0])可能为负数,因此当其为负数时要将其转化为正数,转换的原理为: 41 a%b=(a%b+b)%b 42 当a为负数且b为正数时可使用上述公式将a转换为正数 43 */ 44 if (xy[0] < 0) xy[0] = (xy[0] % m + m) % m; 45 System.out.println("p为" + String.valueOf(p) + ",q为" + String.valueOf(q)); 46 System.out.println("公钥为(" + String.valueOf(n) + ", " + String.valueOf(e) + "),私钥为(" + String.valueOf(n) + ", " + String.valueOf(xy[0]) + ")"); 47 48 // 公钥进行加密(mingwen)^e mod n 49 for (char c : myInfo) { 50 miwen[index++] = myPow((int) c, e, n); 51 } 52 System.out.print("加密后的密文:"); 53 for (int c : miwen) { 54 System.out.print(c + " "); 55 } 56 System.out.println(); 57 58 index = 0; 59 // 私钥进行解密(miwen)^d mod n 60 for (int i : miwen) { 61 mingwen[index] = (char) myPow(miwen[index], xy[0], n); 62 index++; 63 } 64 65 System.out.print("解密后的明文:"); 66 for (char c : mingwen) { 67 System.out.print(c); 68 } 69 70 } 71 72 } 73 74 // 判断一个数是否为素数 75 public static boolean isSuShu(int num) { 76 int max = (int) Math.sqrt(num); 77 for (int i = 2; i <= max; i++) { 78 if (num % i == 0) 79 return false; 80 } 81 return true; 82 } 83 84 // 在素数数组中随机取一个数 85 public static int getRanNum(int size) { 86 return suArr.get((int) (Math.random() * (size))); 87 } 88 89 // 判断两个数是否互质 90 public static int isHuZhi(int a, int b) { 91 return b == 0 ? a : isHuZhi(b, a % b); 92 } 93 94 // 扩展欧几里得算法求得e模m的逆元,从而得到私钥(n, xy[0]),即(n, d) 95 public static void exGcd(int a, int b) { 96 if (b == 0) { 97 xy[0] = 1; 98 xy[1] = 0; 99 } else { 100 exGcd(b, a % b); 101 int x = xy[0]; 102 xy[0] = xy[1]; 103 xy[1] = x - (a / b) * xy[1]; 104 } 105 } 106 107 public static int myPow(int a, int b, int m) { 108 int res = 1; 109 a %= m; 110 while (b != 0) { 111 if ((b & 1) == 1) 112 res = (res * a) % m; 113 a = (a * a) % m; 114 b >>= 1; 115 } 116 return res; 117 } 118 } 119 120 /* 121 * 参考: https://www.jianshu.com/p/fbb8bf7baa97 122 * https://www.cnblogs.com/shuaihui520/p/8954788.html 123 * https://www.cnblogs.com/linkzijun/p/6151486.html 124 */
原文地址:https://www.cnblogs.com/GjqDream/p/11543073.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 详解 Vue 目录及配置文件之 config 目录
- Nginx 搭建静态资源服务
- vue 使用自定义字体
- vue 跨域问题
- Shell 递归查找文件
- element-ui 实现嵌套表格
- Leetcode 第23场双周赛A 5360. 统计最大组的数目 (手速题,map)
- Java 水题系列(4)数组合并
- SpringBoot 整合 SpringDataJPA
- Codeforces Beta Round #51 C. Pie or die(博弈 思维)
- SpringDateJPA 系列之 JPA 中的相关操作
- python Turtle 画出“精美碎花小清新树”快来拿代码!
- SpringDataJPA 系列之 JPA 简介
- Leetcode 264. 丑数 II (数论,三指针,类dp)
- Leetcode 628. 三个数的最大乘积 (数学)