教学服务系统

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

信息计算2019级1班10号张夏楠

[复制链接]

8

主题

20

帖子

98

积分

注册会员

Rank: 2

积分
98
发表于 2022-5-31 10:52:29 | 显示全部楼层 |阅读模式
RSA加密、解密以及签名
  1. package char1;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.InputStream;
  5. import java.security.Key;
  6. import java.security.KeyFactory;
  7. import java.security.KeyPair;
  8. import java.security.KeyPairGenerator;
  9. import java.security.PrivateKey;
  10. import java.security.PublicKey;
  11. import java.security.interfaces.RSAPrivateKey;
  12. import java.security.interfaces.RSAPublicKey;
  13. import java.security.spec.PKCS8EncodedKeySpec;
  14. import java.security.spec.X509EncodedKeySpec;
  15. import java.util.Base64;
  16. import javax.crypto.Cipher;

  17. public class RSAUtil{
  18.        
  19.         public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
  20.        
  21.     /**加密算法RSA*/
  22.     public static final String KEY_ALGORITHM = "RSA";
  23.    
  24.         /**RSA最大加密明文大小*/
  25.     private static final int MAX_ENCRYPT_BLOCK = 117;
  26.    
  27.     /**RSA最大解密密文大小*/
  28.     private static final int MAX_DECRYPT_BLOCK = 128;
  29.        
  30.         /**
  31.         * RSA签名
  32.         * @param content 待签名数据
  33.         * @param privateKey 商户私钥
  34.         * @param input_charset 编码格式
  35.         */
  36.         public static String sign(String content, String privateKey, String input_charset){
  37.         try {
  38.                 PKCS8EncodedKeySpec priPKCS8         = new PKCS8EncodedKeySpec(Base64_.decode(privateKey) );
  39.                 KeyFactory keyf                                 = KeyFactory.getInstance(KEY_ALGORITHM);
  40.                 PrivateKey priKey                                 = keyf.generatePrivate(priPKCS8);
  41.             java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  42.             signature.initSign(priKey);
  43.             signature.update(content.getBytes(input_charset));
  44.             byte[] signed = signature.sign();
  45.             return Base64_.encode(signed);
  46.         }catch (Exception e) {
  47.                 e.printStackTrace();
  48.         }
  49.         return null;
  50.     }
  51.        
  52.         /**
  53.         * RSA验签名检查
  54.         * @param content 待签名数据
  55.         * @param sign 签名值
  56.         * @param ali_public_key 支付宝公钥
  57.         * @param input_charset 编码格式
  58.         */
  59.         public static boolean verify(String content, String sign, String ali_public_key, String input_charset){
  60.                 try {
  61.                         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  62.                 byte[] encodedKey = Base64_.decode(ali_public_key);
  63.                 PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
  64.                         java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
  65.                         signature.initVerify(pubKey);
  66.                         signature.update(content.getBytes(input_charset) );
  67.                         boolean bverify = signature.verify( Base64_.decode(sign) );
  68.                         return bverify;
  69.                 } catch (Exception e) {
  70.                         e.printStackTrace();
  71.                 }
  72.                 return false;
  73.         }
  74.        
  75.         /**
  76.         * 私钥解密
  77.         * @param content 密文
  78.         * @param private_key 商户私钥
  79.         * @param input_charset 编码格式
  80.         */
  81.         public static String decrypt(String content, String private_key, String input_charset) throws Exception {
  82.         PrivateKey prikey = getPrivateKey(private_key);
  83.         Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
  84.         cipher.init(Cipher.DECRYPT_MODE, prikey);
  85.         InputStream ins = new ByteArrayInputStream(Base64_.decode(content));
  86.         ByteArrayOutputStream writer = new ByteArrayOutputStream();
  87.         //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
  88.         byte[] buf = new byte[128];
  89.         int bufl;
  90.         while ((bufl = ins.read(buf)) != -1) {
  91.             byte[] block = null;
  92.             if (buf.length == bufl) {
  93.                 block = buf;
  94.             } else {
  95.                 block = new byte[bufl];
  96.                 for (int i = 0; i < bufl; i++) {
  97.                     block[i] = buf[i];
  98.                 }
  99.             }
  100.             writer.write(cipher.doFinal(block));
  101.         }
  102.         return new String(writer.toByteArray(), input_charset);
  103.     }
  104.        
  105.         /**
  106.      * 公钥加密
  107.      * @param data 源数据
  108.      * @param publicKey 公钥(BASE64编码)
  109.      */
  110.     public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
  111.         byte[] keyBytes = Base64_.decode(publicKey);
  112.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  113.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  114.         Key publicK = keyFactory.generatePublic(x509KeySpec);
  115.         // 对数据加密
  116.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  117.         cipher.init(Cipher.ENCRYPT_MODE, publicK);
  118.         int inputLen = data.length;
  119.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  120.         int offSet = 0;
  121.         byte[] cache;
  122.         int i = 0;
  123.         // 对数据分段加密
  124.         while (inputLen - offSet > 0) {
  125.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
  126.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
  127.             } else {
  128.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);
  129.             }
  130.             out.write(cache, 0, cache.length);
  131.             i++;
  132.             offSet = i * MAX_ENCRYPT_BLOCK;
  133.         }
  134.         byte[] encryptedData = out.toByteArray();
  135.         out.close();
  136.         return encryptedData;
  137.     }
  138.    
  139.     public static String encryptByPublicKeyToStr(byte[] data, String publicKey) throws Exception {
  140.             byte[] bytes = encryptByPublicKey(data, publicKey);
  141.             String result = Base64_.encode(bytes);
  142.             return result;
  143.     }
  144.        
  145.         /**
  146.         * 得到私钥
  147.         * @param key 密钥字符串(经过base64编码)
  148.         * @throws Exception
  149.         */
  150.         public static PrivateKey getPrivateKey(String key) throws Exception {
  151.                 byte[] keyBytes;
  152.                 keyBytes = Base64_.decode(key);
  153.                 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  154.                 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
  155.                 PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  156.                 return privateKey;
  157.         }
  158.        
  159.         public static class Base64_ {
  160.                 private static final Base64.Decoder decoder = Base64.getDecoder();
  161.                 private static final Base64.Encoder encoder = Base64.getEncoder();
  162.                 public static byte[] decode(String key) {
  163.                         if (key == null) { return null;}
  164.                         byte[] decode = decoder.decode(key);
  165.                         return decode;
  166.                 }
  167.                 public static String encode(byte[] content) {
  168.                         if (content == null) {return null;}
  169.                         String encode = encoder.encodeToString(content);
  170.                         return encode;
  171.                 }
  172.         }
  173.        
  174.         /**
  175.          * 测试
  176.          */
  177.         public static void main(String args[]) throws Exception{
  178.         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
  179.         keyPairGen.initialize(1024);
  180.         KeyPair keyPair = keyPairGen.generateKeyPair();
  181.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
  182.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
  183.         String pubKey = Base64_.encode(publicKey.getEncoded()); //公钥
  184.         String priKey = Base64_.encode(privateKey.getEncoded()); //私钥
  185. //        System.out.println(pubKey);
  186. //        System.out.println(priKey);
  187.         
  188. //......................................公钥加密,私钥解密!
  189.         
  190.         String sourceStr = "百度一下,就知道";
  191.         //公钥加密
  192.         byte[] ens = RSAUtil.encryptByPublicKey(sourceStr.getBytes(),pubKey);
  193.         String encodes = Base64_.encode(ens);
  194.         System.out.println("原文: "+sourceStr);
  195.         System.out.println("加密: "+encodes);
  196.         //私钥解密
  197.         String res2 = RSAUtil.decrypt(encodes, priKey, "UTF-8");
  198.         System.out.println("解密:"+res2);
  199.         
  200. //.......................................签名验证,私钥签名,公钥验证是否正确!
  201.         
  202.         String source = "id=shoig&name=shoer&age=23dnjlegj;reg"; //模拟请求参数,然后对此请求参数进行签名。
  203.         
  204.         String sign = RSAUtil.sign(source, priKey, "UTF-8");
  205.         
  206.         System.out.println("签名是:"+sign);
  207.         
  208.         // 公钥验证签名是否正确.
  209.         // 具体流程是,请求参数+sign发送给公钥方,然后公钥方过滤掉sign,用公钥验证其他参数是否通过。
  210.         
  211.         boolean result = RSAUtil.verify(source, sign, pubKey, "UTF-8");
  212.         
  213.         System.out.println(result);
  214.         
  215.         }
  216. }
复制代码
运行截图:



本帖子中包含更多资源

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

x
回复

使用道具 举报

8

主题

20

帖子

98

积分

注册会员

Rank: 2

积分
98
 楼主| 发表于 2022-5-31 15:06:47 | 显示全部楼层
椭圆曲线上公钥密码源码(ECC)

  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. }
复制代码


运行截图:


本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

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

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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