教学服务系统

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

信息计算2019级1班20号李善安

[复制链接]

10

主题

18

帖子

108

积分

注册会员

Rank: 2

积分
108
发表于 2022-6-2 11:27:56 | 显示全部楼层 |阅读模式
本帖最后由 李善安 于 2022-6-2 12:42 编辑

RSA加密算法是一种非对称加密算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。这样就可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
RSA签名的过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。
在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。
总结:公钥加密、私钥解密、私钥签名、公钥验签。
  1. Package basictraing

  2. import org.apache.commons.codec.binary.Base64;
  3. import javax.crypto.Cipher;
  4. import java.io.ByteArrayOutputStream;
  5. import java.security.*;
  6. import java.security.spec.PKCS8EncodedKeySpec;
  7. import java.security.spec.X509EncodedKeySpec;

  8. public class RsaUtil {
  9. //RSA最⼤加密明⽂⼤⼩
  10.         private static final int MAX_ENCRYPT_BLOCK = 117;
  11. //RSA最⼤解密密⽂⼤⼩
  12.         private static final int MAX_DECRYPT_BLOCK = 128;
  13.         public static final String privateKeyA = "privateKeyA";
  14.         public static final String publicKeyA = "publicKeyA";
  15.         public static final String publicKeyB = "publicKeyB";
  16.         public static final String privateKeyB = "privateKeyB";

  17.         public static PrivateKey getPrivateKey(String privateKey) throws Exception {
  18.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  19.                 byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
  20.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
  21.                 return keyFactory.generatePrivate(keySpec);
  22.         }

  23.         public static PublicKey getPublicKey(String publicKey) throws Exception {
  24.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  25.                 byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());
  26.                 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
  27.                 return keyFactory.generatePublic(keySpec);
  28.         }

  29.         public static Map<Integer, String> genKeyPair() throws NoSuchAlgorithmException {
  30.                 // KeyPairGenerator类⽤于⽣成公钥和私钥对,基于RSA算法⽣成对象
  31.                 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  32.                 // 初始化密钥对⽣成器,密钥⼤⼩为96-1024位
  33.                 keyPairGen.initialize(1024, new SecureRandom());
  34.                 // ⽣成⼀个密钥对,保存在keyPair中
  35.                 KeyPair keyPair = keyPairGen.generateKeyPair();
  36.                 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
  37.                 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
  38.                 String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
  39.                 // 得到私钥字符串
  40.                 String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
  41.                 // 将公钥和私钥保存到Map
  42.                 Map<Integer, String> keyMap = new HashMap();
  43.                 keyMap.put(0, publicKeyString); // 0表⽰公钥
  44.                 keyMap.put(1, privateKeyString); // 1表⽰私钥
  45.                 return keyMap;
  46.         }

  47.        
  48.         public static String encrypt(String str, String publicKey) throws Exception {
  49.                 // base64编码的公钥
  50.                 byte[] decoded = Base64.decodeBase64(publicKey);
  51.                 RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
  52.                                 .generatePublic(new X509EncodedKeySpec(decoded));
  53.                 // RSA加密
  54.                 Cipher cipher = Cipher.getInstance("RSA");
  55.                 cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  56.                 byte[] data = str.getBytes("UTF-8");
  57.                 int inputLen = data.length;
  58.                 ByteArrayOutputStream out = new ByteArrayOutputStream();
  59.                 int offSet = 0;
  60.                 byte[] cache;
  61.                 int i = 0;
  62.                 // 对数据分段加密
  63.                 while (inputLen - offSet > 0) {
  64.                         if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  65.                                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  66.                         } else {
  67.                                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  68.                         }
  69.                         out.write(cache, 0, cache.length);
  70.                         i++;
  71.                         offSet = i * MAX_ENCRYPT_BLOCK;
  72.                 }
  73.                 byte[] encryptedData = out.toByteArray();
  74.                 out.close();
  75.                 String outStr = Base64.encodeBase64String(encryptedData);
  76.                 return outStr;
  77.         }

  78.         public static String decrypt(String str, String privateKey) throws Exception {
  79.                 // 64位解码加密后的字符串
  80.                 byte[] data = Base64.decodeBase64(str.getBytes("UTF-8"));
  81.                 // base64编码的私钥
  82.                 byte[] decoded = Base64.decodeBase64(privateKey);
  83.                 RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
  84.                                 .generatePrivate(new PKCS8EncodedKeySpec(decoded));
  85.                 // RSA解密
  86.                 Cipher cipher = Cipher.getInstance("RSA");
  87.                 cipher.init(Cipher.DECRYPT_MODE, priKey);
  88.                 int inputLen = data.length;
  89.                 ByteArrayOutputStream out = new ByteArrayOutputStream();
  90.                 int offSet = 0;
  91.                 byte[] cache;
  92.                 int i = 0;
  93.                 // 对数据分段解密
  94.                 while (inputLen - offSet > 0) {
  95.                         if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  96.                                 cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
  97.                         } else {
  98.                                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  99.                         }
  100.                         out.write(cache, 0, cache.length);
  101.                         i++;
  102.                         offSet = i * MAX_DECRYPT_BLOCK;
  103.                 }
  104.                 byte[] decryptedData = out.toByteArray();
  105.                 out.close();
  106.                 String outStr = new String(decryptedData);
  107.                 return outStr;
  108.         }

  109.         public static String sign(String data, PrivateKey privateKey) throws Exception {
  110.                 byte[] keyBytes = privateKey.getEncoded();
  111.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  112.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  113.                 PrivateKey key = keyFactory.generatePrivate(keySpec);
  114.                 Signature signature = Signature.getInstance("MD5withRSA");
  115.                 signature.initSign(key);
  116.                 signature.update(data.getBytes());
  117.                 return new String(Base64.encodeBase64(signature.sign()));
  118.         }

  119.         public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
  120.                 byte[] keyBytes = publicKey.getEncoded();
  121.                 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  122.                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  123.                 PublicKey key = keyFactory.generatePublic(keySpec);
  124.                 Signature signature = Signature.getInstance("MD5withRSA");
  125.                 signature.initVerify(key);
  126.                 signature.update(srcData.getBytes());
  127.                 return signature.verify(Base64.decodeBase64(sign.getBytes()));
  128.         }
  129. }
复制代码

回复

使用道具 举报

10

主题

18

帖子

108

积分

注册会员

Rank: 2

积分
108
 楼主| 发表于 2022-6-2 11:29:41 | 显示全部楼层
本帖最后由 李善安 于 2022-6-2 12:03 编辑

ECC使用的椭圆曲线定义在有限域p上,p是素数,p>3
2m 域大小为 p = 2m 为一方阵(the field is a square matrix of size p x p)
曲线上的点不连续,限定为离散的整数。域内的点加、点乘结果还在曲线上。
有限域p上的椭圆曲线等式:
y^2 ≡ x ^ 3 + ax + b (mod p)
RSA的密钥空间为域ℤp上的整数 [0…p-1] 。
ECC的密钥用点{x,y},在Galois field ????p 上,x和y都是 [0…p-1]的整数。

椭圆曲线加密算法的过程
公私钥生成:

Alice首先构造一条椭圆曲线E EE,在曲线上选择一点G GG作为生成元,并求G GG的阶为n nn,要求n nn必须为质数;
Alice选择一个私钥k ( k < n ) k (k < n)k(k<n),生成公钥Q = k G Q = kGQ=kG;
Alice将公钥组E 、 Q 、 G E、Q、GE、Q、G发送给Bob。

加密过程:
Bob收到信息后,将明文编码为M MM,M MM为曲线上一点,并选择一个随机数r rr(r < n , n r < n, nr<n,n为G GG的阶);
Bob计算点Cipher1与Cipher2即两段密文,计算方法如下
Cipher1= M + r Q Cipher1 = M + rQCipher1=M+rQ
Cipher2 = r G Cipher2 = rGCipher2=rG
Bob把Cipher1和Cipher2发给Alice。

解密过程:
Alice收到密文后,为了获得M MM,只需要Cipher1 − k ⋅ Cipher2Cipher1 - k · Cipher2Cipher1−k⋅Cipher2,因为
Cipher1 − k ∗ Cipher2 = M + r Q − k r G = M + r k G − k r G = M Cipher1 - k*Cipher2 = M + rQ - krG = M + rkG - krG = MCipher1−k∗Cipher2=M+rQ−krG=M+rkG−krG=M
将M解码即可。
  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. }
复制代码
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 07:50 , Processed in 0.018028 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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