教学服务系统

 找回密码
 立即注册
搜索
查看: 566|回复: 1

信息计算2019级2班14号张柯冕

[复制链接]

8

主题

19

帖子

90

积分

注册会员

Rank: 2

积分
90
发表于 2022-5-31 22:37:18 | 显示全部楼层 |阅读模式
本帖最后由 张柯冕 于 2022-5-31 22:43 编辑
RSA算法

RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法加密和解密使用不同的密钥,即使用加密密钥进行加密、解密密钥进行解密。在RAS算法中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。优点是不需要进行密钥传递,提高了安全性,可以进行数字签名认证。

原理: 1.系统产生两个大素数p, q(保密)
2.计算n=pq(公开),欧拉函数Φ(n)=(p-1)(q-1)(保密)
3.随机选择满足gcd(e,Φ(n))=1的e作为公钥(公开),加密密钥就是(e,n)
4.计算满足ed=1(mod Φ(n))的d作为私钥(保密),解密密钥即为(d,n)

RSA的加解密过程: 首先将明文分组并数字化,每个数字化分组明文的长度不大于log n,然后对每个明文分组m依次进行加解密运算。
1.加密运算:使用公钥e和要加密的明文m进行c=me(mod n)运算即得密文
2.解密运算:使用私钥d和要加密的明文m进行c=md(mod n)运算即得明文。
  1. package RSA;

  2. import java.awt.desktop.SystemEventListener;
  3. import java.util.Scanner;

  4. public class Demo {
  5.     //判断是否是素数
  6.     public static boolean isPrime(long n) {
  7.         boolean b = true;
  8.         for (long i = 2; i <= Math.sqrt(n); i++) {
  9.             if (n % i == 0) {
  10.                 b = false;
  11.                 break;
  12.             } else
  13.                 b = true;
  14.         }
  15.         return b;
  16.     }

  17.     //计算欧拉数
  18.     public static long Euler(long p, long q) {
  19.         return (p - 1) * (q - 1);
  20.     }

  21.     //欧几里得算法求两数的最大公因数---a>b
  22.     static long gcd(long a, long b) {
  23.         if (a < b) {
  24.             long t = a;
  25.             a = b;
  26.             b = t;
  27.         }
  28.         if (a % b == 0) return b;
  29.         else return gcd(b, a % b);
  30.     }

  31.     //求模反元素d(私钥)
  32.     public static long Key(long e, long euler) {
  33.         long key = 1;
  34.         while ((key * e) % euler != 1) {
  35.             key++;
  36.         }
  37.         return key;
  38.     }

  39.     //递归求n次方
  40.     public static long power(long a, long n) {
  41.         long r = 1;
  42.         if (n == 0) r = 1;
  43.         else {
  44.             r = a * power(a, n - 1);
  45.         }
  46.         return r;
  47.     }

  48.     //加密
  49.     public static long encryption(long msg, long e, long n) {
  50.         System.out.println("加密中.......");
  51.         return power(msg, e) % n;
  52.     }

  53.     //解密
  54.     public static long decryption(long c, long key, long n) {
  55.         System.out.println("解密中.......");
  56.         return power(c, key) % n;
  57.     }

  58.     public static void main(String[] args) {
  59.         System.out.println("--------RSA--------");
  60.         //两个大素数
  61.         long p;
  62.         long q;
  63.         System.out.print("输入两个大素数p、q:");
  64.         Scanner sc = new Scanner(System.in);
  65.         p = sc.nextLong();
  66.         q = sc.nextLong();
  67.         // System.out.println("p = " + p + ",q = " + q);
  68.         //判断输入的是否是素数
  69.         boolean b;   //flag
  70.         //判断p
  71.         b = isPrime(p);
  72.         if (b == false) {
  73.             System.out.println("p = " + p + "不是素数。重新输入p!");
  74.             p = sc.nextLong();
  75.             b = isPrime(p);
  76.             while (b = false) {
  77.                 System.out.println("p = " + p + "不是素数。重新输入p!");
  78.                 p = sc.nextLong();
  79.                 b = isPrime(p);
  80.             }
  81.         }
  82.         System.out.println(" p = " + p + "是素数。");

  83.         //判断q
  84.         b = isPrime(q);
  85.         if (b == false) {
  86.             System.out.println("q = " + q + "不是素数。重新输入q!");
  87.             q = sc.nextLong();
  88.             b = isPrime(q);
  89.             while (b = false) {
  90.                 System.out.println("q = " + q + "不是素数。重新输入q!");
  91.                 q = sc.nextLong();
  92.                 b = isPrime(q);
  93.             }
  94.         }
  95.         System.out.println(" q = " + q + "是素数。");
  96.         //打印最终的p、q
  97.         System.out.println("p = " + p + ",q = " + q);

  98.         //计算p、q的欧拉数
  99.         long euler = Euler(p, q);
  100.         System.out.println("Euler(p,q) = " + euler);

  101.         //选取最小的公钥e,1<e<euler,且与euler互质
  102.         long e = 2;
  103.         while (gcd(e, euler) != 1 || e > euler || e < 1) {
  104.             e++;
  105.         }
  106.         System.out.println("e = " + e);

  107.         //求出模反元素(私钥)
  108.         long key = Key(e, euler);
  109.         System.out.println("key = " + key);

  110.         //System.out.println(power(2, 2));
  111.         //加密过程
  112.         System.out.println("输入明文:");
  113.         long msg = sc.nextLong();
  114.         System.out.println("明文:" + msg);
  115.         long c = encryption(msg, e, p * q);//密文
  116.         System.out.println("加密后的密文:" + c);
  117.         //解密过程
  118.         msg = decryption(c, key, p * q);
  119.         System.out.println("解密后的明文:" + msg);

  120.     }
  121. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

8

主题

19

帖子

90

积分

注册会员

Rank: 2

积分
90
 楼主| 发表于 2022-6-2 10:28:17 | 显示全部楼层
ECC算法

ECC是Elliptic Curve Cryptography(椭圆曲线密码学)的缩写,是一种基于椭圆曲线数学的公开密钥加密算法,其本质是利用离散对数问题实现加密。
ECC的主要优势,是在使用更小的密钥的同时,提供更快的性能和更高等级的安全。


ECC算法原理:
描述一条Fp上的椭圆曲线,常用到六个参量:T=(p,a,b,n,x,y)。
(p 、a 、b) 用来确定一条椭圆曲线,p为素数域内点的个数,a和b是其内的两个大数;
x,y为G基点的坐标,也是两个大数;
n为点G基点的阶;
以上六个量就可以描述一条椭圆曲线,有时候我们还会用到h(椭圆曲线上所有点的个数p与n相除的整数部分)。
现在我们描述一个利用椭圆曲线进行加密通信的过程:
1、选定一条椭圆曲线 Ep(a,b) 并取椭圆曲线上一点,作为基点P。
2、选择一个大数k作为私钥,并生成公钥 Q=kP。
3、将 Ep(a,b) 和点Q、P传给用户。
4、用户接到信息后 ,将待传输的明文编码到Ep(a,b)上的一点M,并产生一个随机整数r。
5、公钥加密(密文C是一个点对):
C={rP, M+rQ}
6、私钥解密(M + rQ - k(rP) ,解密结果就是点M),公式如下:

        M + rQ - k(rP) = M + r(kP) - k(rP) = M
7、对点M进行解码就可以得到明文
假设在加密过程中,有一个第三者H,H只能知道椭圆曲线 Ep(a,b)、公钥Q、基点P、密文点C,而通过公钥Q、基点P求私钥k或者通过密文点C、基点P求随机数r都是非常困难的,因此得以保证数据传输的安全。
代码:
  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. using namespace std;

  5. class point
  6. {
  7. public:
  8.         int x;
  9.         int y;
  10. };
  11. point P[100];
  12. int num = 0;

  13. //取模
  14. int my_mod(int a, int p)
  15. {
  16.         //注意负数情况要加上一个p
  17.         int i;
  18.         i = a / p;
  19.         int re = a - i * p;
  20.         if (re >= 0)
  21.         {
  22.                 return re;
  23.         }
  24.         else
  25.         {
  26.                 return re + p;
  27.         }
  28. }

  29. //幂次运算,含模运算,防止溢出
  30. int my_pow(int a, int m, int p)
  31. {
  32.         int result = 1;
  33.         for (int i = 0; i < m; i++)
  34.         {
  35.                 result = (result * a) % p;
  36.         }
  37.         return result;
  38. }

  39. //用于求y,并判断平方根是否为整数
  40. int my_sqrt(int s)
  41. {
  42.         int t;
  43.         t = (int)sqrt(s);
  44.         if (t * t == s)
  45.         {
  46.                 return t;
  47.         }
  48.         else {
  49.                 return -1;
  50.         }
  51. }

  52. void all_points(int a, int b, int p)
  53. {
  54.         for (int i = 0; i < p; i++)
  55.         {
  56.                 int s = i * i * i + a * i + b;
  57.                 while (s < 0)
  58.                 {
  59.                         s += p;
  60.                 }
  61.                 s = my_mod(s, p);
  62.                 //判断是否为平方剩余
  63.                 //p为23,是奇素数
  64.                 //Euler准则
  65.                 int re = my_pow(s, (p - 1) / 2, p);
  66.                 if (re == 1)
  67.                 {
  68.                         //求y
  69.                         int n = 1, y;
  70.                         int f = my_sqrt(s);
  71.                         if (f != -1)
  72.                         {
  73.                                 y = f;
  74.                         }
  75.                         else
  76.                         {
  77.                                 for (; n <= p - 1;)
  78.                                 {
  79.                                         s = s + n * p;
  80.                                         f = my_sqrt(s);
  81.                                         if (f != -1)
  82.                                         {
  83.                                                 y = f;
  84.                                                 break;
  85.                                         }
  86.                                         n++;
  87.                                 }
  88.                         }
  89.                         y = my_mod(y, p);
  90.                         P[num].x = i;
  91.                         P[num].y = y;
  92.                         num++;
  93.                         if (y != 0)
  94.                         {
  95.                                 P[num].x = i;
  96.                                 P[num].y = (p - y) % p;
  97.                                 num++;
  98.                         }
  99.                 }
  100.         }
  101. }

  102. void show()
  103. {
  104.         for (int i = 0; i < num; i++)
  105.         {
  106.                 cout << P[i].x << " " << P[i].y << endl;
  107.         }
  108. }


  109. //扩展欧几里得法,递归法
  110. int extend(int a, int b, int& x, int& y)
  111. {
  112.         if (b == 0)
  113.         {
  114.                 x = 1;
  115.                 y = 0;
  116.                 return a;
  117.         }
  118.         int r = extend(b, a % b, x, y);
  119.         int t = x;
  120.         x = y;
  121.         y = t - a / b * y;
  122.         return r;
  123. }

  124. //借助递归扩展欧几里得求逆
  125. int inv(int a, int b)
  126. {
  127.         int x, y;
  128.         int r = extend(a, b, x, y);
  129.         if (r != 1)
  130.         {
  131.                 return 0;
  132.         }
  133.         x = x % b;
  134.         if (x < 0)
  135.         {
  136.                 x = x + b;
  137.         }
  138.         return x;
  139. }


  140. //两点的加法运算
  141. point add(point p1, point p2, int a, int p)
  142. {
  143.         long t; int flag = 0;
  144.         int x1 = p1.x; int y1 = p1.y;
  145.         int x2 = p2.x; int y2 = p2.y;
  146.         int tx, ty; int x3, y3;

  147.         if ((x2 == x1) && (y2 == y1))
  148.         {
  149.                 //相同点
  150.                 if (y1 == 0)
  151.                 {
  152.                         flag = 1;
  153.                 }
  154.                 else
  155.                 {
  156.                         t = (3 * x1 * x1 + a) * inv(2 * y1, p) % p;
  157.                 }
  158.         }
  159.         else
  160.         {
  161.                 //不同点相加
  162.                 ty = y2 - y1;
  163.                 tx = x2 - x1;
  164.                 while (tx < 0)
  165.                 {
  166.                         tx = tx + p;
  167.                 }
  168.                 while (ty < 0)
  169.                 {
  170.                         ty = ty + p;
  171.                 }

  172.                 if (tx == 0 && ty != 0)
  173.                 {
  174.                         flag = 1;
  175.                 }
  176.                 else
  177.                 {
  178.                         //点不相等
  179.                         t = ty * inv(tx, p) % p;
  180.                 }
  181.         }

  182.         if (flag == 1)
  183.         {
  184.                 //无限点
  185.                 p2.x = -1;
  186.                 p2.y = -1;
  187.         }
  188.         else
  189.         {
  190.                 x3 = (t * t - x1 - x2) % p;
  191.                 y3 = (t * (x1 - x3) - y1) % p;
  192.                 while (x3 < 0)
  193.                 {
  194.                         x3 += p;
  195.                 }
  196.                 while (y3 < 0)
  197.                 {
  198.                         y3 += p;
  199.                 }
  200.                 p2.x = x3;
  201.                 p2.y = y3;
  202.         }
  203.         return p2;
  204. }

  205. //随机选取一个生成元并计算阶
  206. int jie(point& pp, int a, int p)
  207. {
  208.         int ii = rand() % num;
  209.         point P0 = P[ii];
  210.         point p1, p2;
  211.         int number = 1;
  212.         p1.x = P0.x; p2.x = P0.x;
  213.         p1.y = P0.y; p2.y = P0.y;
  214.         while (true)
  215.         {
  216.                 p2 = add(p1, p2, a, p);
  217.                 if (p2.x == -1 && p2.y == -1)
  218.                 {
  219.                         break;
  220.                 }
  221.                 number++;
  222.                 if (p2.x == p1.x)
  223.                 {
  224.                         break;
  225.                 }
  226.         }
  227.         pp.x = p1.x;
  228.         pp.y = p1.y;
  229.         int n = ++number;
  230.         return n;
  231. }

  232. //素数判断
  233. bool judge(int num)
  234. {
  235.         bool ret = true;
  236.         int ubound = sqrt(num) + 1;
  237.         for (int i = 2; i < ubound; i++)
  238.         {
  239.                 if (num % i == 0)
  240.                 {
  241.                         ret = false;
  242.                         break;
  243.                 }
  244.         }
  245.         return ret;
  246. }

  247. //计算kG
  248. point cal(point G, int k, int a, int p)
  249. {
  250.         point temp = G;
  251.         for (int i = 0; i < k - 1; i++)
  252.         {
  253.                 temp = add(temp, G, a, p);
  254.         }
  255.         return temp;
  256. }

  257. int main()
  258. {
  259.         srand(time(NULL));
  260.         int a, b, p;
  261.         point generator; int n;
  262.         char SE[10];
  263.         char CR[10];

  264.         cout << "请输入椭圆曲线群(a,b,p):";
  265.         cin >> a >> b >> p;
  266.         cout << "请输入明文:";
  267.         cin >> SE;
  268.         cout << "请输入密钥:";
  269.         cin >> CR;

  270.         //计算所有点
  271.         all_points(a, b, p);
  272.         //选取生成元,直到阶为素数
  273.         do
  274.         {
  275.                 n = jie(generator, a, p);
  276.         } while (judge(n) == false);
  277.         cout << endl << "选取生成元(" << generator.x << "," << generator.y << "),阶为:" << n << endl;
  278.         //选取私钥
  279.         int ka = int(CR[0]) % (n - 1) + 1;//选取使用的密钥
  280.         point pa = cal(generator, ka, a, p);//计算公钥
  281.         cout << "私钥:" << ka << endl;
  282.         cout << "公钥:(" << pa.x << "," << pa.y << ")" << endl;

  283.         //加密
  284.         int k = 0;//随机数k
  285.         k = rand() % (n - 2) + 1;
  286.         point C1 = cal(generator, k, a, p);//计算C1

  287.         //m嵌入到椭圆曲线
  288.         int t = rand() % num; //选择映射点
  289.         point Pt = P[t];
  290.         point P2 = cal(pa, k, a, p);
  291.         point Pm = add(Pt, P2, a, p);
  292.         cout << endl << "要发送的密文:" << endl;
  293.         cout << "kG=(" << C1.x << "," << C1.y << "),pt+kPa=(" << Pm.x << "," << Pm.y << ")";
  294.         int C[100];
  295.         cout << ",C = { ";
  296.         for (int i = 0; i < strlen(SE); i++)
  297.         {
  298.                 C[i] = int(SE[i]) * Pt.x + Pt.y;//选取要加密的明文
  299.                 cout << C[i] << " ";
  300.         }
  301.         cout << "}" << endl;


  302.         //解密
  303.         point temp, temp1;
  304.         int m;
  305.         temp = cal(C1, ka, a, p);
  306.         temp.y = 0 - temp.y;
  307.         temp1 = add(Pm, temp, a, p);//求解Pt
  308.         printf("\n解密结果:\n");
  309.         for (int i = 0; i < strlen(SE); i++)
  310.         {
  311.                 m = (C[i] - temp1.y) / temp1.x;
  312.                 printf("%c", char(m));//输出密文
  313.         }
  314.         printf("\n");

  315.         return 0;
  316. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:46 , Processed in 0.018890 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表