Java实现RSA加密算法

#记录一下本人上密码学课程上机的实验(勿喷)

#RSA加密过程:

package cryptography.experiment2;

/**
 * @Auther:柚子
 * @Date:2022/10/28-10-28-8:48
 * @Description:cryptography.experiment2
 * @version: 1.0
 */
@SuppressWarnings("all")
public class Experiment2_RSA {

    /**
     * 判断输入的数据是否为素数
     * @param num 输入的数据
     * @return 返回判断结果
     */
    public static boolean isPrime_23(long num) {
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0)
                return false;
        }
        return true;
    }

    /**
     * 判断两个数是否为素数
     * @param num1 表示 p
     * @param num2 表示 q
     * @return 返回两个值是否都满足要求(只有进入了两个if语句中才返回true,否则都返回false)
     */
    public static boolean jugement_23(long num1, long num2) {
        if (isPrime_23(num1)) {
            System.out.println(num1 + "是素数");
            if (isPrime_23(num2)) {
                System.out.println(num2 + "是素数"); // 只有两个的满足了才返回true
                return true;
            } else {
                System.out.println(num2 + "不是素数");
                return false;
            }
        } else {
            System.out.println(num1 + "不是素数");
            return false;
        }
    }


    /**
     * 计算欧拉数
     * @param p
     * @param q
     * @return 返回欧拉数
     */
    public static long Euler_23(long p, long q) {
        return (p - 1) * (q - 1);
    }


    /**
     * 求密钥中的模,即 n
     * @param p
     * @param q
     * @return
     */
    public static long getModular_23(long p, long q) {
        return p * q;
    }


    /**
     * 平方乘方法
     * @param m 要加密的信息
     * @param e 加密信息的指数
     * @return 返回平方乘的结果
     */
    public static long squareMultiplication_23(long m, long e, long mod){
        System.out.println("用平方乘算法的计算过程为:");
        long temp = 1; // 临时变量
        int count = 0; // 计数器
        long last; // 记录密钥末位的值
        while (e > 0){ //如果m不为零
            last = (e & 1);
            if (last == 1){ // 如果当前末位为0,可以不做操作,直接右移,间接忽略了最高位的1
                temp = temp * m % mod;
            }
            m = m * m % mod;
            e >>= 1;
            System.out.println("i= " + (count++) + " ,此时平方乘结果= " + temp);
        }
        return temp;
    }


    /**
     * 模重复平方方法
     * @param m 要加密的信息
     * @param e 加密信息的指数
     * @return 返回模重复平方计算的结果
     */
    public static long moduloRepeatingSquared_23(long m, long e, long mod){
        System.out.println("用模重复平方方法的计算过程为:");
        String index = Long.toBinaryString(e); // 将指数化成二进制的形式
        char[] indexes = index.toCharArray(); // 将字符串二进制数化成字符型数组
        long result = 1;
        for (int i = 0; i < indexes.length; i++) {
            if (indexes[i] == '1'){
                result = result * result * m % mod;
            }else {
                result = result * result % mod;
            }
            System.out.println("i= " + i + " ,此时模重复平方计算结果= " + result);
        }
        return result;
    }


    /**
     * 判断 e 是否和欧拉数互质且满足要求
     * @param e 随机选的一个整数
     * @param euler 欧拉数
     * @return 是否符合要求的结果
     */
    public static boolean choose_23(long e, long euler){
        if (isPrime_23(e) && e > 1 && e < euler){
            return true;
        }else {
            return false;
        }
    }


    /**
     * 拓展欧几里得算法,求 d 私钥
     * @param euler
     * @param e
     * @return 返回私钥,但是还没有判断其正负性
     */
    public static long expandEuclid_23(long euler, long e){
        // a 是被除数,b 是除数 ,c是商, d是余数
        long a = euler, b = e, c, d = 1, s = 0, t = 0;
        long s1 = 1, s2 = 0, t1 = 0, t2 = 1;
        while (d != 0){
            c = a / b;
            d = a % b;
            s = s1 -c * s2;
            t = t1 - c * t2;
            if (d != 0){
                a = b;
                b = d;
                s1 = s2;
                s2 = s;
                t1 = t2;
                t2 = t;
            }
        }

        return t2;
    }
}

#测试代码

package cryptography.experiment2;

import java.util.Scanner;

/**
 * @Auther:柚子
 * @Date:2022/10/31-10-31-23:43
 * @Description:cryptography.experiment2
 * @version: 1.0
 */
@SuppressWarnings("all")
public class Test_RSA {
    public static void main(String[] args) {
        System.out.println("RSA加密算法测试:");
        Scanner scan = new Scanner(System.in);
        long p, q;
        while (true){
            System.out.println("请输入两个大素数:");
            System.out.print("p= ");
            p = scan.nextLong();
            System.out.print("q= ");
            q = scan.nextLong();
            if (Experiment2_RSA.jugement_23(p,q)){ //如果输入的两个数都为素数则跳出循环
                break;
            }
        }

        long mod = Experiment2_RSA.getModular_23(p,q); // 计算p q的乘积
        System.out.println("p , q的乘积 mod= " + mod);

        long euler23 = Experiment2_RSA.Euler_23(p, q); // 计算欧拉数
        System.out.println("欧拉数= " + euler23);

        long e; //公钥
        while (true){
            System.out.println("请输入和欧拉数互质,且满足大于1 小于欧拉数的公钥:");
            System.out.print("e= ");
            e = scan.nextLong(); // 读取公钥
            if (Experiment2_RSA.choose_23(e,euler23)){
                break;
            }
        }

        long d = Experiment2_RSA.expandEuclid_23(euler23,e);
        if (d < 0){
            d += euler23;
        }
        System.out.println("根据欧几里得拓展算法得,私钥d= " + d);

        System.out.print("请输入你要机密的信息m= ");
        long m = scan.nextLong();
        long c = Experiment2_RSA.squareMultiplication_23(m,e,mod);
        System.out.println("调用平方乘,使用公钥加密得到密文c= " + c);

        System.out.println();
        long msg = Experiment2_RSA.moduloRepeatingSquared_23(c,d,mod);
        System.out.println("调用模重复平方法,使用解密得到明文m= " + msg);
    }
}

#测试结果
RSA运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BYYQ1030

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

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

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

打赏作者

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

抵扣说明:

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

余额充值