手撕RSA加密算法

RSA加密算法(思路):
1:选择两个大素数p,   q(p,q需严格保密,一般在100位以上)
      实例:设p  =  47,  q  =  71(计算方便所以举简单数字的例子)
2:计算n  =  p  *  q,  r  =  (p  -  1)(q  -  1)
      实例:n  =  47  *   71  =  3337    r  =  46  *   70  =  3220
3:选择一个公钥e,要求e  <  r且 e不是r的因子
      实例:e  =  79
4:选择私钥d,满足 (d  *  e) mod r  =  1
      实例:代入:d  *  79 mod  3220  =  1 得到  d  =  1019
5:销毁p,q 的记录
6:加密过程:明文pt,加密私钥e,密文ct
      计算公式:ct  =  p t e pt^e pte mod n
      实例:明文2021,加密后ct  =  2538
7:解密过程:
      计算公式:pt  =  c t d ct^d ctd mod n


代码实现:

//RSA算法(java实现)

import java.io.*;

public class RSA {

    private int p = 0, q = 0;
    private long n = 0, r = 0, e = 0, d = 0;

    private long pt = 0;//明文
    private long ct = 0;//密文
    private long word = 0;//解密后明文

    //判断是否为素数(试除法)
    public boolean isPrime(long t) {
        if (t == 1) return false;
        for (int i = 2; i <= t / i; i++)
            if (t % i == 0)
                return false;
        return true;
    }

    //求最大公因数(欧几里得算法)
    public long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    //p, q, n, r, e, d
    public void start() throws Exception {
        //输入素数p
        System.out.println("请输入素数p: ");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            this.p = Integer.parseInt(bufferedReader.readLine());
            if (isPrime(this.p)) break;
            else System.out.println("您输入的不是素数,请重新输入p");
        }

        //输入素数q
        System.out.println("请输入素数q: ");
        while (true) {
            this.q = Integer.parseInt(bufferedReader.readLine());
            if (isPrime(this.q)) break;
            else System.out.println("您输入的不是素数,请重新输入q");
        }

        this.n = this.p * this.q;
        this.r = (p - 1) * (q - 1);
        System.out.println("这两个素数的乘积n为:" + this.n);
        System.out.println("n的欧拉数=(p-1)(q-1):" + this.r);

        getE();
        getD();
    }

    //提供一个公钥e,这个值要求小于r并且不是r的因子
    public void getE() throws Exception {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入公钥: ");
        while (true) {
            this.e = Long.parseLong(bufferedReader.readLine());
            if (this.e < this.r && r % this.e != 0)
                break;
        }
        System.out.println("公钥为:" + this.e);
    }

    //计算密钥(欧几里得扩展法)
    public void getD() {
        long value = 1;
        for (long i = 1; ; i++) {
            value = i * this.r + 1;
            //System.out.println("value:  " + value);
            if ((value % this.e == 0) && (value / this.e < this.r)) {
                this.d = value / this.e;
                break;
            }
        }
        System.out.println("生成的私钥为:" + this.d);
    }


    //输入需要加密的明文
    public void getPt() throws Exception {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("请输入明文:");
        this.pt = Long.parseLong(bufferedReader.readLine());
    }

    //(快速幂)
    public long qmi(long a, long b, long p) {
        long res = 1;
        while (b > 0) {
            if ((b & 1) != 0) res = res * a % p;
            b = b >> 1;
            a = a * a % p;
        }
        return res;
    }

    //加密后解密
    public void RSAMain() throws Exception {
        this.getPt();
        System.out.println("输入的明文为: " + this.pt);
        //加密
        this.ct = this.qmi(this.pt, this.e, this.n);
        System.out.println("算出的密文为:" + this.ct);
        //解密
        this.word = this.qmi(this.ct, this.d, this.n);
        System.out.println("解密后所得的明文为:" + this.word);

    }

    //入口
    public static void main(String[] args) throws Exception {
        RSA t = new RSA();
        t.start();
        t.RSAMain();
    }
}

效果展示:
在这里插入图片描述
代码很多地方还需要完善,比如大素数

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I'm 程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值