教学服务系统

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

信息计算2019级1班9号陈佳怡

[复制链接]

8

主题

15

帖子

84

积分

注册会员

Rank: 2

积分
84
发表于 2022-6-2 14:33:37 | 显示全部楼层 |阅读模式
RSA加密与签名算法

一 RSA算法简介

  RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。

二 RSA加密、签名区别

  加密和签名都是为了安全性考虑,但略有不同。简单的说,加密是为了防止信息被泄露,而签名是为了防止信息被篡改。

三 实现代码

  1. import java.io.ByteArrayInputStream;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.InputStream;
  4. import java.security.Key;
  5. import java.security.KeyFactory;
  6. import java.security.KeyPair;
  7. import java.security.KeyPairGenerator;
  8. import java.security.PrivateKey;
  9. import java.security.PublicKey;
  10. import java.security.interfaces.RSAPrivateKey;
  11. import java.security.interfaces.RSAPublicKey;
  12. import java.security.spec.PKCS8EncodedKeySpec;
  13. import java.security.spec.X509EncodedKeySpec;
  14. import java.util.Base64;
  15. import javax.crypto.Cipher;

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



本帖子中包含更多资源

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

x
回复

使用道具 举报

8

主题

15

帖子

84

积分

注册会员

Rank: 2

积分
84
 楼主| 发表于 2022-6-2 15:14:43 | 显示全部楼层
ECC加密算法

一 算法简介

  椭圆曲线加密算法,简称ECC,是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全。

二 代码实现

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<math.h>
  5. #include<time.h>
  6. #define MAX 100

  7. typedef struct point {
  8.         int point_x;
  9.         int point_y;
  10. }Point;
  11. typedef struct ecc {
  12.         struct point p[MAX];
  13.         int len;
  14. }ECCPoint;
  15. typedef struct generator {
  16.         Point p;
  17.         int p_class;
  18. }GENE_SET;

  19. void get_all_points();
  20. int int_sqrt(int s);
  21. Point timesPiont(int k, Point p);
  22. Point add_two_points(Point p1, Point p2);
  23. int inverse(int n, int b);
  24. void get_generetor_class();
  25. void encrypt_ecc();
  26. void decrypt_ecc();
  27. int mod_p(int s);
  28. void print();
  29. int isPrime(int n);

  30. char alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
  31. int a = -1, b = 0, p = 89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)
  32. ECCPoint eccPoint;
  33. GENE_SET geneSet[MAX];
  34. int geneLen;
  35. char plain[] = "yes";
  36. int m[MAX];
  37. int cipher[MAX];
  38. int nB;//私钥
  39. Point P1, P2, Pt, G, PB;
  40. Point Pm;
  41. int C[MAX];

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

  182. //倍点运算的递归算法
  183. Point timesPiont(int k, Point p0)
  184. {
  185.         if (k == 1) {
  186.                 return p0;
  187.         }
  188.         else if (k == 2) {
  189.                 return add_two_points(p0, p0);
  190.         }
  191.         else {
  192.                 return add_two_points(p0, timesPiont(k - 1, p0));
  193.         }
  194. }

  195. //两点的加法运算
  196. Point add_two_points(Point p1, Point p2)
  197. {
  198.         long t;
  199.         int x1 = p1.point_x;
  200.         int y1 = p1.point_y;
  201.         int x2 = p2.point_x;
  202.         int y2 = p2.point_y;
  203.         int tx, ty;
  204.         int x3, y3;
  205.         int flag = 0;
  206.         //求
  207.         if ((x2 == x1) && (y2 == y1))
  208.         {
  209.                 //相同点相加
  210.                 if (y1 == 0)
  211.                 {
  212.                         flag = 1;
  213.                 }
  214.                 else {
  215.                         t = (3 * x1 * x1 + a) * inverse(p, 2 * y1) % p;
  216.                 }
  217.                 //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
  218.         }
  219.         else {
  220.                 //不同点相加
  221.                 ty = y2 - y1;
  222.                 tx = x2 - x1;
  223.                 while (ty < 0)
  224.                 {
  225.                         ty += p;
  226.                 }
  227.                 while (tx < 0)
  228.                 {
  229.                         tx += p;
  230.                 }
  231.                 if (tx == 0 && ty != 0)
  232.                 {
  233.                         flag = 1;
  234.                 }
  235.                 else {
  236.                         t = ty * inverse(p, tx) % p;
  237.                 }
  238.         }
  239.         if (flag == 1)
  240.         {
  241.                 p2.point_x = -1;
  242.                 p2.point_y = -1;
  243.         }
  244.         else {
  245.                 x3 = (t * t - x1 - x2) % p;
  246.                 y3 = (t * (x1 - x3) - y1) % p;
  247.                 //使结果在有限域GF(P)上
  248.                 while (x3 < 0)
  249.                 {
  250.                         x3 += p;
  251.                 }
  252.                 while (y3 < 0)
  253.                 {
  254.                         y3 += p;
  255.                 }
  256.                 p2.point_x = x3;
  257.                 p2.point_y = y3;
  258.         }
  259.         return p2;
  260. }
  261. //求b关于n的逆元
  262. int inverse(int n, int b)
  263. {
  264.         int q, r, r1 = n, r2 = b, t, t1 = 0, t2 = 1, i = 1;
  265.         while (r2 > 0)
  266.         {
  267.                 q = r1 / r2;
  268.                 r = r1 % r2;
  269.                 r1 = r2;
  270.                 r2 = r;
  271.                 t = t1 - q * t2;
  272.                 t1 = t2;
  273.                 t2 = t;
  274.         }
  275.         if (t1 >= 0)
  276.                 return t1 % n;
  277.         else {
  278.                 while ((t1 + i * n) < 0)
  279.                         i++;
  280.                 return t1 + i * n;
  281.         }
  282. }
  283. //求出椭圆曲线上所有点
  284. void get_all_points()
  285. {
  286.         int i = 0;
  287.         int j = 0;
  288.         int s, y = 0;
  289.         int n = 0, q = 0;
  290.         int modsqrt = 0;
  291.         int flag = 0;
  292.         if (4 * a * a * a + 27 * b * b != 0)
  293.         {
  294.                 for (i = 0; i <= p - 1; i++)
  295.                 {
  296.                         flag = 0;
  297.                         n = 1;
  298.                         y = 0;
  299.                         s = i * i * i + a * i + b;
  300.                         while (s < 0)
  301.                         {
  302.                                 s += p;
  303.                         }
  304.                         s = mod_p(s);
  305.                         modsqrt = int_sqrt(s);
  306.                         if (modsqrt != -1)
  307.                         {
  308.                                 flag = 1;
  309.                                 y = modsqrt;
  310.                         }
  311.                         else {
  312.                                 while (n <= p - 1)
  313.                                 {
  314.                                         q = s + n * p;
  315.                                         modsqrt = int_sqrt(q);
  316.                                         if (modsqrt != -1)
  317.                                         {
  318.                                                 y = modsqrt;
  319.                                                 flag = 1;
  320.                                                 break;
  321.                                         }
  322.                                         flag = 0;
  323.                                         n++;
  324.                                 }
  325.                         }
  326.                         if (flag == 1)
  327.                         {
  328.                                 eccPoint.p[j].point_x = i;
  329.                                 eccPoint.p[j].point_y = y;
  330.                                 j++;
  331.                                 if (y != 0)
  332.                                 {
  333.                                         eccPoint.p[j].point_x = i;
  334.                                         eccPoint.p[j].point_y = (p - y) % p;
  335.                                         j++;
  336.                                 }
  337.                         }
  338.                 }
  339.                 eccPoint.len = j;//点集个数
  340.                 print(); //打印点集
  341.         }
  342. }

  343. //取模函数
  344. int mod_p(int s)
  345. {
  346.         int i;        //保存s/p的倍数
  347.         int result;        //模运算的结果
  348.         i = s / p;
  349.         result = s - i * p;
  350.         if (result >= 0)
  351.         {
  352.                 return result;
  353.         }
  354.         else
  355.         {
  356.                 return result + p;
  357.         }
  358. }

  359. //判断平方根是否为整数
  360. int int_sqrt(int s)
  361. {
  362.         int temp;
  363.         temp = (int)sqrt(s);//转为整型
  364.         if (temp * temp == s)
  365.         {
  366.                 return temp;
  367.         }
  368.         else {
  369.                 return -1;
  370.         }
  371. }
  372. //打印点集
  373. void print()
  374. {
  375.         int i;
  376.         int len = eccPoint.len;
  377.         printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n", len + 1);
  378.         for (i = 0; i < len; i++)
  379.         {
  380.                 if (i % 8 == 0)
  381.                 {
  382.                         printf("\n");
  383.                 }
  384.                 printf("(%2d,%2d)\t", eccPoint.p[i].point_x, eccPoint.p[i].point_y);
  385.         }
  386.         printf("\n");
  387. }
复制代码
三 运行截图




本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-4-30 02:03 , Processed in 0.015900 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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