教学服务系统

 找回密码
 立即注册
搜索
查看: 661|回复: 2

信息计算2019级1班3号刘丹丹

[复制链接]

9

主题

19

帖子

99

积分

注册会员

Rank: 2

积分
99
发表于 2022-5-2 22:05:11 | 显示全部楼层 |阅读模式
                                                                              大数RSA算法的实现
一.原理:RSA算法的具体描述如下:
1. 随意选择两个大的质数p和q,p不等于q,计算N = pq.
2. 根据欧拉函数,求得r=φ(N)=φ(p)φ(q)=(p-1)(q-1)。
3. 选择一个小于r的整数e,是e与r互质。并求得e关于r的模反元素,命名为d。(求d令ed≡1(mod r))。(模反元素存在,当且仅当e与r互质)
4. 将p和q的记录销毁。
其中(N,e)是公钥,(N,d)是私钥。用到了求模逆,互质关系,欧拉函数等数学知识


二.源程序:
  1. import java.math.*;
  2. import java.util.*;

  3. public class Test1 {
  4.     public static BigInteger Prime(BigInteger N)
  5.     {
  6.         boolean f1 = true;
  7.         boolean f2 = true;
  8.         BigInteger E = null;
  9.         while (f1)
  10.         {
  11.             int e = (int) (Math.random() * 1000000000 + 2);
  12.             E = new BigInteger(String.valueOf(e));
  13.             BigInteger a = BigInteger.ZERO;
  14.             while (f2) {
  15.                 a = E.mod(N);
  16.                 if (a.equals(BigInteger.ZERO))
  17.                     break;
  18.                 else
  19.                     E = N;
  20.                 N = a;
  21.                 if (N.equals(BigInteger.ONE)) {
  22.                     f1 = false;
  23.                     f2 = false;
  24.                     E = new BigInteger(String.valueOf(e));
  25.                 }
  26.             }
  27.         }
  28.         return E;
  29.     }
  30.     public static void main(String[] args){
  31.         Random rad = new Random();
  32.         BigInteger P = BigInteger.probablePrime(100, rad);
  33.         BigInteger Q = BigInteger.probablePrime(100, rad);
  34.         P = new BigInteger("1422190779664435130578574872464189487159269521438844277069165347989379651477195077278520918544216091165328330" +
  35.                 "37439126553885228505041962156920856757540374980634188741118614578251050137701249084108411224753759631562279017912889888838823830260852615022162119976454139351863355473841839316049016083961001571120119");
  36.         Q = new BigInteger("1154063353988317882630621327580284079361812526326427928762763251614128450514432787184549821060375619085643258410" +
  37.                 "08562548113013126674531705009431442852270585480837050915675733690296476470166027390822965804009765817418751368137319529407681332211027693672973572001086145050157986459263311606907760630228706795319");
  38.         BigInteger N = P.multiply(Q);
  39.         BigInteger M = (P.subtract(BigInteger.ONE)).multiply((Q.subtract(BigInteger.ONE)));
  40.         BigInteger E = Prime(N);
  41.         //E =  BigInteger.probablePrime(100,rad);
  42.         //E = new BigInteger("13");
  43.         BigInteger D = oula(E,M);
  44.         // 加密
  45.         String mingwen = "";
  46.         System.out.println("明文:");
  47.         Scanner scanner1 = new Scanner(System.in);
  48.         if(scanner1.hasNext())
  49.         {
  50.             mingwen = scanner1.nextLine();
  51.         }
  52.         byte[] bytes = new byte[mingwen.length()];
  53.         for (int i = 0;i < mingwen.length();i++)
  54.         {
  55.             bytes[i] = Byte.valueOf((byte) mingwen.charAt(i));
  56.         }
  57.         BigInteger a = new BigInteger(1,bytes);
  58.         BigInteger b = a.modPow(E,N);
  59.         System.out.println("密文为: " + b);
  60.         // 解密
  61.         String miwen = null;
  62.         System.out.println("输入密文:");
  63.         Scanner scanner2 = new Scanner(System.in);
  64.         if(scanner2.hasNext())
  65.         {
  66.             miwen = scanner2.nextLine();
  67.         }
  68.         BigInteger c = new BigInteger(miwen);
  69.         BigInteger d = c.modPow(D,N);
  70.         byte[] bytes2 = new byte[miwen.length()];
  71.         bytes2 = d.toByteArray();
  72.         System.out.print("密文为: ");
  73.         for (int i = 0; i < bytes2.length; ++i)
  74.             System.out.print((char) bytes2[i]);
  75.     }
  76.     public static BigInteger oula(BigInteger E, BigInteger M){
  77.         boolean f = true;
  78.         BigInteger a = new BigInteger("1");
  79.         BigInteger b = new BigInteger("0");
  80.         BigInteger c = M;
  81.         BigInteger d = E;
  82.         BigInteger temp, s;
  83.         while (f)
  84.         {
  85.             temp = c.remainder(d);
  86.             if (temp.compareTo(BigInteger.ZERO) == 0)
  87.                 f = false;
  88.             s = c.divide(d);
  89.             c = d;
  90.             d = temp;
  91.             temp = b.subtract(a.multiply(s));
  92.             b = a;
  93.             if (f)
  94.                 a = temp;
  95.         }
  96.         if (a.compareTo(BigInteger.ZERO) < 0)
  97.             return a.add(M);
  98.         else
  99.             return b;
  100.     }
  101. }
复制代码

三.程序截图:




本帖子中包含更多资源

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

x
回复

使用道具 举报

9

主题

19

帖子

99

积分

注册会员

Rank: 2

积分
99
 楼主| 发表于 2022-5-30 22:11:29 | 显示全部楼层
本帖最后由 2019-1刘丹丹 于 2022-5-30 22:16 编辑

                                                                                          RSA大数算法改进版

在之前的基础上,对RSA大数算法进行改进,重写,程序为:
  1. package 密码学RSA;

  2. import java.math.BigInteger;
  3. import java.util.Random;
  4. import java.util.Scanner;

  5. public class RSA大数版本 {

  6.         public static BigInteger Mod_ni(BigInteger a, BigInteger b) {
  7.                 BigInteger zero = new BigInteger("0");
  8.                 a = a.subtract(b.multiply(a.divide(b))); // a = a - b * (a / b)
  9.                 int i = 0;
  10.                 BigInteger bb = b;
  11.                 BigInteger s[] = new BigInteger[1024];
  12.                 while (a.compareTo(zero) != 0) { // a != 0
  13.                         s[i] = b.divide(a); // s[i] = b / a
  14.                         BigInteger t = b;
  15.                         b = a;
  16.                         a = t.mod(a); // t % a
  17.                         i++;
  18.                 }
  19.                 BigInteger y[] = new BigInteger[i];
  20.                 y[0] = new BigInteger("1");
  21.                 y[1] = s[0];
  22.                 for (int j = 2; j < i; j++)
  23.                         y[j] = (y[j - 1].multiply(s[j - 1])).add(y[j - 2]); // y[j] = y[j - 1] * s[j - 1] + y[j - 2]
  24.                 if ((i - 1) % 2 == 1)
  25.                         y[i - 1] = bb.subtract(y[i - 1]); // y[i - 1] = bb - y[i - 1]
  26.                 return y[i - 1];
  27.         }

  28.         public static void main(String args[]) {
  29.                 BigInteger one = new BigInteger("1");
  30.                 Random rnd = new Random();
  31.                 BigInteger p = new BigInteger("1");
  32.                 BigInteger q = new BigInteger("1");
  33.                 p = BigInteger.probablePrime(1024, rnd);
  34.                 q = BigInteger.probablePrime(1024, rnd);
  35.                 BigInteger n = p.multiply(q); // n = p * q
  36.                 BigInteger f = (p.subtract(one).multiply(q.subtract(one))); // f = (p - 1) * (q - 1)
  37.                 BigInteger e = new BigInteger("65537");
  38.                 while (true) {
  39.                         e = BigInteger.probablePrime(1024, rnd);
  40.                         if (e.compareTo(f) <= 1)
  41.                                 break;
  42.                 }
  43.                 BigInteger d = Mod_ni(e, f);
  44.                 System.out.println("n = " + n);
  45.                 System.out.println("公钥:" + e);
  46.                 System.out.println("私钥:" + d);

  47.                 BigInteger xx, yy;
  48.                 while (true) {
  49.                         System.out.println("请选择功能: \n0.退出 \n1.加密\n2.解密");
  50.                         Scanner scan1 = new Scanner(System.in);
  51.                         int ch = scan1.nextInt();
  52.                         if (ch == 1) {
  53.                                 System.out.println("请输入明文:");
  54.                                 String mingwen = new String();
  55.                                 Scanner scan2 = new Scanner(System.in);
  56.                                 mingwen = scan2.nextLine();
  57.                                 byte x[] = new byte[mingwen.length()];
  58.                                 for (int i = 0; i < mingwen.length(); i++)
  59.                                         x[i] = Byte.valueOf((byte) mingwen.charAt(i));                        
  60.                                 xx = new BigInteger(x);  // 字节数组转大整型
  61.                                 xx = xx.modPow(e, n);  // xx^e mod n
  62.                                 System.out.println("密文为:" + xx);
  63.                         } else if (ch == 2) {
  64.                                 System.out.println("请输入密文:");
  65.                                 String miwen = new String();
  66.                                 Scanner scan3 = new Scanner(System.in);
  67.                                 miwen = scan3.nextLine();
  68.                                 yy = new BigInteger(miwen);
  69.                                 yy = yy.modPow(d, n);   // yy^d mod n
  70.                                 byte[] y = yy.toByteArray(); // 大整型转字节数组
  71.                                 System.out.print("明文为:");
  72.                                 for (int i = 0; i < y.length; ++i)
  73.                                         System.out.print((char) y[i]);
  74.                                 System.out.print('\n');
  75.                         } else
  76.                                 break;
  77.                 }

  78.         }
  79. }
复制代码

本帖子中包含更多资源

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

x
回复

使用道具 举报

9

主题

19

帖子

99

积分

注册会员

Rank: 2

积分
99
 楼主| 发表于 2022-5-30 23:07:45 | 显示全部楼层
本帖最后由 2019-1刘丹丹 于 2022-5-31 11:22 编辑

                                                                                                             RSA签名
一.简介
  (1)签名就是在这份资料后面增加一段强而有力的证明,以此证明这段信息的发布者和这段信息的有效性完整性。
  (2)RSA签名常用的就是将这份信息进行hash,得到一个hash值,再将hash值加密作为签名,后缀在信息的末尾。
  (3)哈希的好处:更安全,签名更快,解除了签名长度的限制。


二.具体实现过程
    RSA数字签名算法的过程为:A明文m用解密变换作: (公钥用来加密,私钥用来解密,数字签名是用私钥完成的,所以称为解密变换,这与onu sdk中一致)sº Dk (m)=md mod n,其中d,n为A的私人密钥,只有A才知道它;B收到A的签名后,用A的公钥和加密变换得到明文,因: Ek(s)= Ek(Dk (m))= (md)e mod n,又 deº1 mod j(n)即de=lj(n)+1,根据欧拉定理mj(n)=1 mod n,所以Ek(s)=mlj(n)+1=[mj(n)]em=m mod n。若明文m和签名s一起送给用户B,B可以确信信息确实是A发送的。同时A也不能否认送给这个信息,因为除了A本人外,其他任何人都无法由明文m产生s.因此RSA数字签名方案是可行的。


1 签名算法:签名算法包括消息摘要计算,RSA加密。

(1)    消息摘要计算。  消息在签名前首先通过MD5计算,生成128位的消息摘要  digest。

(2)    对摘要作RSA计算。  用加密算法,采用签名者的私钥加密消息摘要,得到加密后的字符串。加密算法中使用的加密块为01类型。

2 验证签名算法

   验证签名算法包括两步:RSA解密得签名者的消息摘要,验证者对原消息计算摘要,比较两个消息摘要。验证签名的过程输入为消息,签名者的公钥,签名;输出为验证的结果,即是否是正确的签名。

(1)    RSA解密。  签名实际是加密的字符串。用3.5所述的解密算法,采用签名者的公钥对这个加密的字符串解密。解密的结果应为128位的消息摘要。在解密过程中,若出现得到的加密块的类型不是01,则解密失败。签名不正确。

(2)    消息摘要计算和比较。  验证者对消息用MD5算法重新计算,得到验证者自己的消息摘要。验证者比较解密得到的消息摘要和自己的消息摘要,如果两者相同,则验证成功,可以确认消息的完整性及签名确实为签名者的;否则,验证失败。



三.源代码:

  1. import random
  2. import hashlib

  3. def judge(m, s, n, e):
  4.     return m == ''.join([chr(kuaisumi(i, e, n)) for i in s])

  5. def gcd(a, b):
  6.     if a % b == 0:
  7.         return b
  8.     else:
  9.         return gcd(b, a % b)

  10. def kuaisumi(a, n, p):
  11.     c = 1
  12.     str = bin(n)[2:][::-1]
  13.     for item in str:
  14.         if item == '1':
  15.             c = (c * a) % p
  16.             a = (a ** 2) % p
  17.         elif item == '0':
  18.             a = (a ** 2) % p
  19.     return c

  20. def dasushu(w):
  21.     while True:
  22.         number = random.randint(2 ** (w - 1), 2 ** w - 1) | 1
  23.         for i in range(50):
  24.             if not ceshisushu(number):
  25.                 break
  26.             if i == 49:
  27.                 return number

  28. def key():
  29.     p = dasushu(512)
  30.     q = dasushu(512)

  31.     n = p * q
  32.     _n = (p - 1) * (q - 1)

  33.     while True:
  34.         e = random.randint(2, _n - 1)
  35.         if gcd(e, _n) == 1:
  36.             break
  37.     d = euclid(e, _n)
  38.     return n, e, d

  39. def ceshisushu(num):
  40.     s = num - 1
  41.     k = 0
  42.     while s % 2 == 0:
  43.         s = s // 2
  44.         k = k + 1
  45.     a = random.randint(2, num)
  46.     b = kuaisumi(a, s, num)
  47.     if b == 1:
  48.         return True
  49.     for i in range(k):
  50.         if b == num - 1:
  51.             return True
  52.         else:
  53.             b = b * b % num
  54.     return False

  55. def euclid(x, n):
  56.     r0 = n
  57.     r1 = x % n
  58.     if r1 == 1:
  59.         y = 1
  60.     else:
  61.         s0 = 1
  62.         s1 = 0
  63.         t0 = 0
  64.         t1 = 1
  65.         while r0 % r1 != 0:
  66.             q = r0 // r1
  67.             r = r0 % r1
  68.             r0 = r1
  69.             r1 = r
  70.             s = s0 - q * s1
  71.             s0 = s1
  72.             s1 = s
  73.             t = t0 - q * t1
  74.             t0 = t1
  75.             t1 = t
  76.             if r == 1:
  77.                 y = (t + n) % n
  78.     return y

  79. def sign(m, n, d):
  80.     s = [kuaisumi(ord(i), d, n) for i in m]
  81.     return m, s

  82. if __name__ == '__main__':
  83.     message = input('请输入原文:').encode('utf-8')
  84.     m = hashlib.sha512(message).hexdigest()
  85.     n, e, d = key()
  86.     m, s = sign(m, n, d)
  87.     print('长度:', len(s))
  88.     with open('sign.txt', 'w') as f:
  89.         f.write(str(s).replace('[', '').replace(']', '').replace(',', '\n').replace(' ', ''))
  90.     print('是否成功?', judge(m, s, n, e))
复制代码


四.运行截图:



本帖子中包含更多资源

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

x
回复

使用道具 举报

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

本版积分规则

教学服务系统

GMT+8, 2025-9-20 02:34 , Processed in 0.021366 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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