教学服务系统

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

信息计算2019级1班7号徐佳颖

[复制链接]

8

主题

21

帖子

80

积分

注册会员

Rank: 2

积分
80
发表于 2022-6-2 20:39:12 | 显示全部楼层 |阅读模式
RSA加密解密及数字签名


一、RSA简介

     RSA是目前应用最广泛地一种非对称秘码体制。它的安全性基于大整数的因式分解问题。RSA是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年一起提出的.PSA对极大整数做因数分解的难度决定了 RSA 算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用 RSA 加密的信息的可靠性就会极度下降。


二、算法实现(C#)

  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;

  4. namespace RSACryption
  5. {
  6.     class RSACSPSample
  7.     {
  8.         static void Main()
  9.         {
  10.             try
  11.             {

  12.                 string str_DataToSign = @"Data to Sign!Data to Sign!Data to Sign!";
  13.                 Console.WriteLine("原文:" + str_DataToSign);
  14.                 Console.WriteLine("长度:" + str_DataToSign.Length.ToString());
  15.                 Console.WriteLine();

  16.                 RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();

  17.                 string str_Private_Key = Convert.ToBase64String(RSAalg.ExportCspBlob(true));
  18.                 string str_Public_Key = Convert.ToBase64String(RSAalg.ExportCspBlob(false));
  19.                 Console.WriteLine("公钥:" + str_Public_Key);
  20.                 Console.WriteLine();
  21.                 Console.WriteLine("私钥:" + str_Private_Key);
  22.                 Console.WriteLine();

  23.                 string str_SignedData = HashAndSign(str_DataToSign, str_Private_Key);// Hash and sign the data.
  24.                 Console.WriteLine("签名数据:" + str_SignedData);
  25.                 Console.WriteLine();

  26.                 if (VerifySignedHash(str_DataToSign, str_SignedData, str_Public_Key))
  27.                 {
  28.                     Console.WriteLine("验证签名OK.");
  29.                 }
  30.                 else
  31.                 {
  32.                     Console.WriteLine("签名不匹配!");
  33.                 }
  34.                 Console.WriteLine();

  35.             }
  36.             catch (ArgumentNullException)
  37.             {
  38.                 Console.WriteLine("The data was not signed or verified");

  39.             }
  40.         }

  41.         //对数据签名
  42.         public static string HashAndSign(string str_DataToSign, string str_Private_Key)
  43.         {
  44.             ASCIIEncoding ByteConverter = new ASCIIEncoding();
  45.             byte[] DataToSign = ByteConverter.GetBytes(str_DataToSign);
  46.             try
  47.             {
  48.                 RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
  49.                 RSAalg.ImportCspBlob(Convert.FromBase64String(str_Private_Key));
  50.                 byte[] signedData = RSAalg.SignData(DataToSign, new SHA1CryptoServiceProvider());
  51.                 string str_SignedData = Convert.ToBase64String(signedData);
  52.                 return str_SignedData;
  53.             }
  54.             catch (CryptographicException e)
  55.             {
  56.                 Console.WriteLine(e.Message);
  57.                 return null;
  58.             }
  59.         }

  60.         //验证签名
  61.         public static bool VerifySignedHash(string str_DataToVerify, string str_SignedData, string str_Public_Key)
  62.         {
  63.             byte[] SignedData = Convert.FromBase64String(str_SignedData);

  64.             ASCIIEncoding ByteConverter = new ASCIIEncoding();
  65.             byte[] DataToVerify = ByteConverter.GetBytes(str_DataToVerify);
  66.             try
  67.             {
  68.                 RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
  69.                 RSAalg.ImportCspBlob(Convert.FromBase64String(str_Public_Key));

  70.                 return RSAalg.VerifyData(DataToVerify, new SHA1CryptoServiceProvider(), SignedData);

  71.             }
  72.             catch (CryptographicException e)
  73.             {
  74.                 Console.WriteLine(e.Message);

  75.                 return false;
  76.             }
  77.         }
  78.     }

  79. }
复制代码


三、运行截图




本帖子中包含更多资源

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

x
回复

使用道具 举报

8

主题

21

帖子

80

积分

注册会员

Rank: 2

积分
80
 楼主| 发表于 2022-6-2 20:50:40 | 显示全部楼层
椭圆曲线加密算法(ECC)

一、ECC简介        椭圆曲线加密算法,简称ECC,是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全,RSA加密算法也是一种非对称加密算法,在公开密钥加密和电子商业中RSA被广泛使用。


二、算法实现(C)
  1. /*
  2. (1)编程计算该椭圆曲线上所有在有限域GF(89)上的点;
  3. (2)编程实现椭圆曲线上任意一个点P(例如P=(12,5))的倍点运算的递归算法,即计算k*P( k=2,3,…);(重点!)
  4. (3)利用此递归算法找出椭圆曲线上的所有生成元G以及它们的阶n,即满足n*G=O;
  5. (4)设计实现某一用户B的公钥、私钥算法,即得到public key=(n, G, PB, Ep(a, b))
  6. secure key=nB(小于n)
  7. (5)假如用户A发送明文消息“yes”并加密传输给用户B,用户B接收消息后要能解密为明文。试用ECC密码体制实现此功能。
  8. */


  9. #include<stdio.h>
  10. #include<stdlib.h>
  11. #include<string.h>
  12. #include<math.h>
  13. #include<time.h>
  14. #define MAX 100

  15. typedef struct point {
  16.         int point_x;
  17.         int point_y;
  18. }Point;
  19. typedef struct ecc {
  20.         struct point p[MAX];
  21.         int len;
  22. }ECCPoint;
  23. typedef struct generator {
  24.         Point p;
  25.         int p_class;
  26. }GENE_SET;

  27. void get_all_points();
  28. int int_sqrt(int s);
  29. Point timesPiont(int k, Point p);
  30. Point add_two_points(Point p1, Point p2);
  31. int inverse(int n, int b);
  32. void get_generetor_class();
  33. void encrypt_ecc();
  34. void decrypt_ecc();
  35. int mod_p(int s);
  36. void print();
  37. int isPrime(int n);

  38. char alphabet[26] = "abcdefghijklmnopqrstuvwxy";
  39. int a = -1, b = 0, p = 89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)
  40. ECCPoint eccPoint;
  41. GENE_SET geneSet[MAX];
  42. int geneLen;
  43. char plain[] = "yes";
  44. int m[MAX];
  45. int cipher[MAX];
  46. int nB;//私钥
  47. Point P1, P2, Pt, G, PB;
  48. Point Pm;
  49. int C[MAX];

  50. int main()
  51. {
  52.         get_generetor_class();
  53.         encrypt_ecc();
  54.         decrypt_ecc();
  55.         return 0;
  56. }
  57. //task4:加密
  58. void encrypt_ecc()
  59. {
  60.         int num, i, j;
  61.         int gene_class;
  62.         int num_t;
  63.         int k;
  64.         srand(time(NULL));
  65.         //明文转换过程
  66.         for (i = 0; i < strlen(plain); i++)
  67.         {
  68.                 for (j = 0; j < 26; j++) //for(j=0;j<26;j++)
  69.                 {
  70.                         if (plain[i] == alphabet[j])
  71.                         {
  72.                                 m[i] = j;//将字符串明文换成数字,并存到整型数组m里面
  73.                         }
  74.                 }
  75.         }
  76.         //选择生成元
  77.         num = rand() % geneLen;
  78.         gene_class = geneSet[num].p_class;
  79.         while (isPrime(gene_class) == -1)//不是素数
  80.         {
  81.                 num = rand() % (geneLen - 3) + 3;
  82.                 gene_class = geneSet[num].p_class;
  83.         }
  84.         //printf("gene_class=%d\n",gene_class);
  85.         G = geneSet[num].p;
  86.         //printf("G:(%d,%d)\n",geneSet[num].p.point_x,geneSet[num].p.point_y);
  87.         nB = rand() % (gene_class - 1) + 1;//选择私钥
  88.         PB = timesPiont(nB, G);
  89.         printf("\n公钥:\n");
  90.         printf("{y^2=x^3%d*x+%d,%d,(%d,%d),(%d,%d)}\n", a, b, gene_class, G.point_x, G.point_y, PB.point_x, PB.point_y);
  91.         printf("私钥:\n");
  92.         printf("nB=%d\n", nB);
  93.         //加密
  94.         //
  95.         k = rand() % (gene_class - 2) + 1;
  96.         P1 = timesPiont(k, G);
  97.         //
  98.         num_t = rand() % eccPoint.len; //选择映射点
  99.         Pt = eccPoint.p[num_t];
  100.         //printf("Pt:(%d,%d)\n",Pt.point_x,Pt.point_y);
  101.         P2 = timesPiont(k, PB);
  102.         Pm = add_two_points(Pt, P2);
  103.         printf("加密数据:\n");
  104.         printf("kG=(%d,%d),Pt+kPB=(%d,%d),C={", P1.point_x, P1.point_y, Pm.point_x, Pm.point_y);
  105.         for (i = 0; i < strlen(plain); i++)
  106.         {
  107.                 //                num_t=rand()%eccPoint.len; //选择映射点
  108.                 //                Pt=eccPoint.p[num_t];
  109.                 C[i] = m[i] * Pt.point_x + Pt.point_y;
  110.                 printf("{%d}", C[i]);
  111.         }
  112.         printf("}\n");
  113. }
  114. //task5:解密
  115. void decrypt_ecc()
  116. {
  117.         Point temp, temp1;
  118.         int m, i;
  119.         temp = timesPiont(nB, P1);
  120.         temp.point_y = 0 - temp.point_y;
  121.         temp1 = add_two_points(Pm, temp);//求解Pt
  122. //        printf("(%d,%d)\n",temp.point_x,temp.point_y);
  123. //        printf("(%d,%d)\n",temp1.point_x,temp1.point_y);
  124.         printf("\n解密结果:\n");
  125.         for (i = 0; i < strlen(plain); i++)
  126.         {
  127.                 m = (C[i] - temp1.point_y) / temp1.point_x;
  128.                 printf("%c", alphabet[m]);//输出密文
  129.         }
  130.         printf("\n");
  131. }
  132. //判断是否为素数
  133. int isPrime(int n)
  134. {
  135.         int i, k;
  136.         k = sqrt(n);
  137.         for (i = 2; i <= k; i++)
  138.         {
  139.                 if (n % i == 0)
  140.                         break;
  141.         }
  142.         if (i <= k) {
  143.                 return -1;
  144.         }
  145.         else {
  146.                 return 0;
  147.         }
  148. }
  149. //task3:求生成元以及阶
  150. void get_generetor_class()
  151. {
  152.         int i, j = 0;
  153.         int count = 1;
  154.         Point p1, p2;
  155.         get_all_points();
  156.         //        p1.point_x=p2.point_x=3;
  157.         //        p1.point_y=p2.point_y=2;
  158.         //        while(1)
  159.         //        {
  160.         //                printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  161.         //                p2=add_two_points(p1,p2);
  162.         //                count++;
  163.         //                if(p2.point_x==-1 && p2.point_y==-1)
  164.         //                {
  165.         //                        break;
  166.         //                }
  167.         //        }
  168.         //        printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
  169.                 //
  170.         //        do{
  171.         //                        printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  172.         //                        p2=add_two_points(p1,p2);
  173.         //                        count++;
  174.         //                       
  175.         //        } while(!((p2.point_x==p1.point_x)&&(p2.point_y==p1.point_y)));
  176.         //        printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
  177.         //        count ++ ;
  178.         //        printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
  179.         printf("\n**********************************输出生成元以及阶:*************************************\n");
  180.         for (i = 0; i < eccPoint.len; i++)
  181.         {
  182.                 count = 1;
  183.                 p1.point_x = p2.point_x = eccPoint.p[i].point_x;
  184.                 p1.point_y = p2.point_y = eccPoint.p[i].point_y;
  185.                 while (1)
  186.                 {
  187.                         p2 = add_two_points(p1, p2);
  188.                         if (p2.point_x == -1 && p2.point_y == -1)
  189.                         {
  190.                                 break;
  191.                         }
  192.                         count++;
  193.                         if (p2.point_x == p1.point_x)
  194.                         {
  195.                                 break;
  196.                         }
  197.                 }
  198.                 count++;
  199.                 if (count <= eccPoint.len + 1)
  200.                 {
  201.                         geneSet[j].p.point_x = p1.point_x;
  202.                         geneSet[j].p.point_y = p1.point_y;
  203.                         geneSet[j].p_class = count;
  204.                         printf("(%d,%d)--->>%d\t", geneSet[j].p.point_x, geneSet[j].p.point_y, geneSet[j].p_class);
  205.                         j++;
  206.                         if (j % 6 == 0) {
  207.                                 printf("\n");
  208.                         }
  209.                 }
  210.                 geneLen = j;
  211.         }
  212. }

  213. //task2:倍点运算的递归算法
  214. Point timesPiont(int k, Point p0)
  215. {
  216.         if (k == 1) {
  217.                 return p0;
  218.         }
  219.         else if (k == 2) {
  220.                 return add_two_points(p0, p0);
  221.         }
  222.         else {
  223.                 return add_two_points(p0, timesPiont(k - 1, p0));
  224.         }
  225. }

  226. //两点的加法运算
  227. Point add_two_points(Point p1, Point p2)
  228. {
  229.         long t;
  230.         int x1 = p1.point_x;
  231.         int y1 = p1.point_y;
  232.         int x2 = p2.point_x;
  233.         int y2 = p2.point_y;
  234.         int tx, ty;
  235.         int x3, y3;
  236.         int flag = 0;
  237.         //求
  238.         if ((x2 == x1) && (y2 == y1))
  239.         {
  240.                 //相同点相加
  241.                 if (y1 == 0)
  242.                 {
  243.                         flag = 1;
  244.                 }
  245.                 else {
  246.                         t = (3 * x1 * x1 + a) * inverse(p, 2 * y1) % p;
  247.                 }
  248.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  249.         }
  250.         else {
  251.                 //不同点相加
  252.                 ty = y2 - y1;
  253.                 tx = x2 - x1;
  254.                 while (ty < 0)
  255.                 {
  256.                         ty += p;
  257.                 }
  258.                 while (tx < 0)
  259.                 {
  260.                         tx += p;
  261.                 }
  262.                 if (tx == 0 && ty != 0)
  263.                 {
  264.                         flag = 1;
  265.                 }
  266.                 else {
  267.                         t = ty * inverse(p, tx) % p;
  268.                 }
  269.         }
  270.         if (flag == 1)
  271.         {
  272.                 p2.point_x = -1;
  273.                 p2.point_y = -1;
  274.         }
  275.         else {
  276.                 x3 = (t * t - x1 - x2) % p;
  277.                 y3 = (t * (x1 - x3) - y1) % p;
  278.                 //使结果在有限域GF(P)上
  279.                 while (x3 < 0)
  280.                 {
  281.                         x3 += p;
  282.                 }
  283.                 while (y3 < 0)
  284.                 {
  285.                         y3 += p;
  286.                 }
  287.                 p2.point_x = x3;
  288.                 p2.point_y = y3;
  289.         }
  290.         return p2;
  291. }
  292. //求b关于n的逆元
  293. int inverse(int n, int b)
  294. {
  295.         int q, r, r1 = n, r2 = b, t, t1 = 0, t2 = 1, i = 1;
  296.         while (r2 > 0)
  297.         {
  298.                 q = r1 / r2;
  299.                 r = r1 % r2;
  300.                 r1 = r2;
  301.                 r2 = r;
  302.                 t = t1 - q * t2;
  303.                 t1 = t2;
  304.                 t2 = t;
  305.         }
  306.         if (t1 >= 0)
  307.                 return t1 % n;
  308.         else {
  309.                 while ((t1 + i * n) < 0)
  310.                         i++;
  311.                 return t1 + i * n;
  312.         }
  313. }
  314. //task1:求出椭圆曲线上所有点
  315. void get_all_points()
  316. {
  317.         int i = 0;
  318.         int j = 0;
  319.         int s, y = 0;
  320.         int n = 0, q = 0;
  321.         int modsqrt = 0;
  322.         int flag = 0;
  323.         if (4 * a * a * a + 27 * b * b != 0)
  324.         {
  325.                 for (i = 0; i <= p - 1; i++)
  326.                 {
  327.                         flag = 0;
  328.                         n = 1;
  329.                         y = 0;
  330.                         s = i * i * i + a * i + b;
  331.                         while (s < 0)
  332.                         {
  333.                                 s += p;
  334.                         }
  335.                         s = mod_p(s);
  336.                         modsqrt = int_sqrt(s);
  337.                         if (modsqrt != -1)
  338.                         {
  339.                                 flag = 1;
  340.                                 y = modsqrt;
  341.                         }
  342.                         else {
  343.                                 while (n <= p - 1)
  344.                                 {
  345.                                         q = s + n * p;
  346.                                         modsqrt = int_sqrt(q);
  347.                                         if (modsqrt != -1)
  348.                                         {
  349.                                                 y = modsqrt;
  350.                                                 flag = 1;
  351.                                                 break;
  352.                                         }
  353.                                         flag = 0;
  354.                                         n++;
  355.                                 }
  356.                         }
  357.                         if (flag == 1)
  358.                         {
  359.                                 eccPoint.p[j].point_x = i;
  360.                                 eccPoint.p[j].point_y = y;
  361.                                 j++;
  362.                                 if (y != 0)
  363.                                 {
  364.                                         eccPoint.p[j].point_x = i;
  365.                                         eccPoint.p[j].point_y = (p - y) % p;
  366.                                         j++;
  367.                                 }
  368.                         }
  369.                 }
  370.                 eccPoint.len = j;//点集个数
  371.                 print(); //打印点集
  372.         }
  373. }

  374. //取模函数
  375. int mod_p(int s)
  376. {
  377.         int i;        //保存s/p的倍数
  378.         int result;        //模运算的结果
  379.         i = s / p;
  380.         result = s - i * p;
  381.         if (result >= 0)
  382.         {
  383.                 return result;
  384.         }
  385.         else
  386.         {
  387.                 return result + p;
  388.         }
  389. }

  390. //判断平方根是否为整数
  391. int int_sqrt(int s)
  392. {
  393.         int temp;
  394.         temp = (int)sqrt(s);//转为整型
  395.         if (temp * temp == s)
  396.         {
  397.                 return temp;
  398.         }
  399.         else {
  400.                 return -1;
  401.         }
  402. }
  403. //打印点集
  404. void print()
  405. {
  406.         int i;
  407.         int len = eccPoint.len;
  408.         printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n", len + 1);
  409.         for (i = 0; i < len; i++)
  410.         {
  411.                 if (i % 8 == 0)
  412.                 {
  413.                         printf("\n");
  414.                 }
  415.                 printf("(%2d,%2d)\t", eccPoint.p[i].point_x, eccPoint.p[i].point_y);
  416.         }
  417.         printf("\n");
  418. }
复制代码


三、运行截图

本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 01:54 , Processed in 0.016383 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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