教学服务系统

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

信息计算2019级1班23号姚俣譞

[复制链接]

12

主题

17

帖子

82

积分

注册会员

Rank: 2

积分
82
发表于 2022-5-30 17:00:33 | 显示全部楼层 |阅读模式
本帖最后由 姚俣譞 于 2022-5-30 17:59 编辑

一、RSA加解密和签名


1、RSA加密
   RSA的密文是对代表了明文的数字的E次方求mod N的结果。换句话说,就是将明文和自己做E次乘方,然后将其结果除以N求余数,这个余数就是密文。
   即:密文 = 明文E mod N
  只要知道E和N,就可以完成加密, 因此E和N的组合{E,N},就是「公钥」。
2、RSA解密
  将密文自己做D次乘法,再对其结果除以N求余数,就可以得到明文。(解密的N和加密的N是同一个)
  即:明文 = 密文D mod N
  知道了D和N,就可以完成解密,因此D和N的组合{D,N},就是私钥。
3.代码和运行        (代码见后面跟的帖子)


二、ECC算法

    ECC是建立在基于椭圆曲线的离散对数问题上的密码体制,给定椭圆曲线上的一个点G,并选取一个整数k,求解K=kG很容易,反过来,在椭圆曲线上给定两个点K和G,若使K=kG,求整数k是一个难题。ECC就是建立在此数学难题之上,这一数学难题称为椭圆曲线离散对数问题。其中椭圆曲线上的点K则为公钥,整数k则为私钥。


代码和运行如下:
  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.         int i;
  17.         i = a / p;
  18.         int re = a - i * p;
  19.         if (re >= 0)
  20.         {
  21.                 return re;
  22.         }
  23.         else
  24.         {
  25.                 return re + p;
  26.         }
  27. }

  28. int my_pow(int a, int m, int p)
  29. {
  30.         int result = 1;
  31.         for (int i = 0; i < m; i++)
  32.         {
  33.                 result = (result * a) % p;
  34.         }
  35.         return result;
  36. }

  37. int my_sqrt(int s)
  38. {
  39.         int t;
  40.         t = (int)sqrt(s);
  41.         if (t * t == s)
  42.         {
  43.                 return t;
  44.         }
  45.         else {
  46.                 return -1;
  47.         }
  48. }

  49. void all_points(int a, int b, int p)
  50. {
  51.         for (int i = 0; i < p; i++)
  52.         {
  53.                 int s = i * i * i + a * i + b;
  54.                 while (s < 0)
  55.                 {
  56.                         s += p;
  57.                 }
  58.                 s = my_mod(s, p);

  59.                 int re = my_pow(s, (p - 1) / 2, p);
  60.                 if (re == 1)
  61.                 {
  62.                         //求y
  63.                         int n = 1, y;
  64.                         int f = my_sqrt(s);
  65.                         if (f != -1)
  66.                         {
  67.                                 y = f;
  68.                         }
  69.                         else
  70.                         {
  71.                                 for (; n <= p - 1;)
  72.                                 {
  73.                                         s = s + n * p;
  74.                                         f = my_sqrt(s);
  75.                                         if (f != -1)
  76.                                         {
  77.                                                 y = f;
  78.                                                 break;
  79.                                         }
  80.                                         n++;
  81.                                 }
  82.                         }
  83.                         y = my_mod(y, p);
  84.                         P[num].x = i;
  85.                         P[num].y = y;
  86.                         num++;
  87.                         if (y != 0)
  88.                         {
  89.                                 P[num].x = i;
  90.                                 P[num].y = (p - y) % p;
  91.                                 num++;
  92.                         }
  93.                 }
  94.         }
  95. }

  96. void show()
  97. {
  98.         for (int i = 0; i < num; i++)
  99.         {
  100.                 cout << P[i].x << " " << P[i].y << endl;
  101.         }
  102. }


  103. int extend(int a, int b, int& x, int& y)
  104. {
  105.         if (b == 0)
  106.         {
  107.                 x = 1;
  108.                 y = 0;
  109.                 return a;
  110.         }
  111.         int r = extend(b, a % b, x, y);
  112.         int t = x;
  113.         x = y;
  114.         y = t - a / b * y;
  115.         return r;
  116. }

  117. //递归扩展欧几里得求逆
  118. int inv(int a, int b)
  119. {
  120.         int x, y;
  121.         int r = extend(a, b, x, y);
  122.         if (r != 1)
  123.         {
  124.                 return 0;
  125.         }
  126.         x = x % b;
  127.         if (x < 0)
  128.         {
  129.                 x = x + b;
  130.         }
  131.         return x;
  132. }


  133. //加法运算
  134. point add(point p1, point p2, int a, int p)
  135. {
  136.         long t; int flag = 0;
  137.         int x1 = p1.x; int y1 = p1.y;
  138.         int x2 = p2.x; int y2 = p2.y;
  139.         int tx, ty; int x3, y3;

  140.         if ((x2 == x1) && (y2 == y1))
  141.         {
  142.                 //相同点
  143.                 if (y1 == 0)
  144.                 {
  145.                         flag = 1;
  146.                 }
  147.                 else
  148.                 {
  149.                         t = (3 * x1 * x1 + a) * inv(2 * y1, p) % p;
  150.                 }
  151.         }
  152.         else
  153.         {
  154.                 //不同点
  155.                 ty = y2 - y1;
  156.                 tx = x2 - x1;
  157.                 while (tx < 0)
  158.                 {
  159.                         tx = tx + p;
  160.                 }
  161.                 while (ty < 0)
  162.                 {
  163.                         ty = ty + p;
  164.                 }

  165.                 if (tx == 0 && ty != 0)
  166.                 {
  167.                         flag = 1;
  168.                 }
  169.                 else
  170.                 {
  171.                         //点不相等
  172.                         t = ty * inv(tx, p) % p;
  173.                 }
  174.         }

  175.         if (flag == 1)
  176.         {
  177.                 //无限点
  178.                 p2.x = -1;
  179.                 p2.y = -1;
  180.         }
  181.         else
  182.         {
  183.                 x3 = (t * t - x1 - x2) % p;
  184.                 y3 = (t * (x1 - x3) - y1) % p;
  185.                 while (x3 < 0)
  186.                 {
  187.                         x3 += p;
  188.                 }
  189.                 while (y3 < 0)
  190.                 {
  191.                         y3 += p;
  192.                 }
  193.                 p2.x = x3;
  194.                 p2.y = y3;
  195.         }
  196.         return p2;
  197. }

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

  225. //素数判断
  226. bool judge(int num)
  227. {
  228.         bool ret = true;
  229.         int ubound = sqrt(num) + 1;
  230.         for (int i = 2; i < ubound; i++)
  231.         {
  232.                 if (num % i == 0)
  233.                 {
  234.                         ret = false;
  235.                         break;
  236.                 }
  237.         }
  238.         return ret;
  239. }

  240. //计算kG
  241. point cal(point G, int k, int a, int p)
  242. {
  243.         point temp = G;
  244.         for (int i = 0; i < k - 1; i++)
  245.         {
  246.                 temp = add(temp, G, a, p);
  247.         }
  248.         return temp;
  249. }

  250. int main()
  251. {
  252.         srand(time(NULL));
  253.         int a, b, p;
  254.         point generator; int n;
  255.         char SE[10];
  256.         char CR[10];

  257.         cout << "请输入椭圆曲线群(a,b,p):";
  258.         cin >> a >> b >> p;
  259.         cout << "请输入明文:";
  260.         cin >> SE;
  261.         cout << "请输入密钥:";
  262.         cin >> CR;

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

  276.         //加密
  277.         int k = 0;//随机数k
  278.         k = rand() % (n - 2) + 1;
  279.         point C1 = cal(generator, k, a, p);//计算C1

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


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

  308.         return 0;
  309. }
复制代码






本帖子中包含更多资源

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

x
回复

使用道具 举报

12

主题

17

帖子

82

积分

注册会员

Rank: 2

积分
82
 楼主| 发表于 2022-5-30 17:55:13 | 显示全部楼层
本帖最后由 姚俣譞 于 2022-5-30 17:59 编辑

附上第一个报告的代码 不知道为什么编辑直接弄没了
  1. package test;


  2. import javax.crypto.Cipher;
  3. import java.nio.charset.StandardCharsets;
  4. import java.security.*;
  5. import java.security.interfaces.RSAPrivateKey;
  6. import java.security.interfaces.RSAPublicKey;
  7. import java.security.spec.PKCS8EncodedKeySpec;
  8. import java.security.spec.X509EncodedKeySpec;
  9. import java.util.Base64;
  10. import java.util.HashMap;
  11. import java.util.Map;


  12. public class RsaCoder {
  13.     private static Map<Integer, String> keyMap = new HashMap<>();  


  14.     public static void main(String[] args) throws Exception {
  15.         //生成公钥和私钥
  16.         genKeyPair();
  17.         //加密字符串
  18.         String message = "As broken mirror never put together,see you never again.";

  19.         String messageEn = encrypt(message, keyMap.get(0));
  20.         System.out.println(message + "\t加密后的字符串为:" + messageEn);
  21.         String messageDe = decrypt(messageEn, keyMap.get(1));
  22.         System.out.println("还原后的字符串为:" + messageDe+"亦如破镜难圆,后会无期");
  23.     }



  24.     public static String encrypt(String str, String publicKey) throws Exception {
  25.         PublicKey pubKey = getPublicKey(publicKey);
  26.         //RSA加密
  27.         Cipher cipher = Cipher.getInstance("RSA");//Java 默认的 RSA 实现是 "RSA/None/PKCS1Padding"
  28.         cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  29.         String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
  30.         return outStr;
  31.     }

  32.    
  33.     public static String decrypt(String str, String privateKey) throws Exception {
  34.         //64位解码加密后的字符串
  35.         byte[] inputByte = Base64.getDecoder().decode(str.getBytes());
  36.         //得到RSAPrivateKey
  37.         PrivateKey priKey = getPrivateKey(privateKey);
  38.         //RSA解密
  39.         Cipher cipher = Cipher.getInstance("RSA");
  40.         cipher.init(Cipher.DECRYPT_MODE, priKey);
  41.         String outStr = new String(cipher.doFinal(inputByte));
  42.         return outStr;
  43.     }

  44.     // 从string转public key
  45.     public static PublicKey getPublicKey(String key) throws Exception {
  46.         byte[] keyBytes = Base64.getDecoder().decode(key);
  47.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  48.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  49.         PublicKey publicKey = keyFactory.generatePublic(keySpec);
  50.         return publicKey;
  51.     }

  52.     // 从string转private key
  53.     public static PrivateKey getPrivateKey(String key) throws Exception {
  54.         byte[] keyBytes;
  55.         keyBytes = Base64.getDecoder().decode(key);
  56.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  57.         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  58.         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  59.         return privateKey;
  60.     }


  61.     private static void genKeyPair() throws NoSuchAlgorithmException {

  62.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  63.       
  64.         keyPairGen.initialize(1024, new SecureRandom());
  65.         
  66.         KeyPair keyPair = keyPairGen.generateKeyPair();
  67.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
  68.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
  69.         String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
  70.         // 得到私钥字符串
  71.         String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
  72.         // 将公钥和私钥保存到Map
  73.         keyMap.put(0, publicKeyString);  //0表示公钥
  74.         keyMap.put(1, privateKeyString);  //1表示私钥
复制代码
回复

使用道具 举报

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

本版积分规则

教学服务系统

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

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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