Java實現的RSA算法,含加密解密算法,不使用工具類jar

import java.util.Scanner;
public class RsaUtil {
    private long p,q;//輸入的兩個素數p、q
    private long n;//兩個素數p、q的乘積之和n
    private long phi;//n的歐拉函數值phi=(p-1)*(q-1)
    private long e;//公鑰
    private long d;//密鑰
    final static int MAXLENGTH=500;//定義數組的個數的最大值
    private int size=0;//用於表示明文/密文的數組的整數的(實際個數+1)
    public long[] clear=new long[MAXLENGTH];//明文
    public long[] Ciphertext=new long[MAXLENGTH];//密文
    public long[] decryptionText=new long[MAXLENGTH];//解密後的明文
    public  boolean primenumber(long t){
        //判斷是否爲素數
        boolean test=true;
        long k=0;
        k=(long)Math.sqrt((double)t);
        outer:
        for(int i=2;i<=k;i++){
            if((t%i)==0){
                test=false;
                break outer;
            }
        }
        return test;
    }
    public void inputPQ() throws Exception{
        //輸入兩個素數p、q
        Scanner input =new Scanner(System.in);
        do{
            System.out.println("請輸入素數p:");
            p=input.nextLong();
        }while(!primenumber(this.p));
        do{
            System.out.println("請輸入素數q:");
            q=input.nextLong();
            }while(!primenumber(this.q));
        n=p*q;             //兩個素數的乘積n
        phi=(p-1)*(q-1);  //計算歐拉函數值phi
        System.out.println("這兩個素數的乘積n="+p+"*"+q+"="+n);
        System.out.println("所得的"+n+"的歐拉函數值phi="+(p-1)+"*"+(q-1)+"="+phi);
    }
    public long gcd(long a,long b){
        //求兩個數的最大公約數,採用遞歸算法
        long temp;
        if(b==0)
            temp=a;
        else
            temp=gcd(b,a%b);
        return temp;
    }
    public void getPublicKey() throws Exception{
        //求出公鑰e
        for(int i=0;;i++){
            e=(long)(Math.random()*(this.phi+1));//由系統隨機產生一個與phi互質且小於phi的正整數e
            while((e==0)||(e==1)){
                e=(long)(Math.random()*(this.phi+1));//避免系統產生的e爲零或1
            }
            if((this.gcd(phi, e)==1)&&(e<phi))
                break;
        }
        System.out.println("系統自動產生一個與"+phi+"互素且比"+phi+"小的整數e:"+e);
        System.out.println("產生的公鑰{e,n}={"+this.e+","+n+"}");
    }
    public void getPrivateKey(){
        //利用Euclid算法計算獲得私鑰d
        long value=1;
        outer:
            for(long i=1;;i++){
                //e*d=1(mod phi)
                value=i*this.phi+1;
                if((value%this.e==0)&&(value/this.e<this.phi)){
                    d =value/this.e;
                    break outer;
                }
            }
        System.out.println("產生的私鑰{d,n}={"+this.d+","+n+"}");
    }
    public void encryption() throws Exception{
        //加密算法
        Scanner input =new Scanner(System.in);
        System.out.println("請輸入明文,要求輸入的所要加密的是小於"+n+"的正整數(個數不超過MAXLENGTH=500,以輸入-1爲結束標誌):");
         //輸入要加密的明文
        for(int i=0;i<MAXLENGTH;i++){
            clear[i]=input.nextLong();
            while(clear[i]>=n){
                System.out.println("請輸入比"+n+"小的值");
                clear[i]=input.nextLong();
            }
            size++; //記錄明文的數組的整數的(實際個數+1),包括-1在內
            if(clear[i]==-1)//當輸入-1時中止輸入的循環語句
                break;
        }   
        System.out.print("輸入的明文爲:"); //輸出鍵盤輸入的明文
        for(int i=0;i<size-1;i++)
            System.out.print(clear[i]);
        System.out.println();
        for(int k=0;k<size-1;k++)
            Ciphertext[k]=1;  //Ciphertext[]初始化爲1
        long count;
        for(int j=0;j<size-1;j++){
            count=this.e;//count表示加密時的次方數
            if(clear[j]==-1)
                break;
            while(count>0){
                Ciphertext[j]=(Ciphertext[j]*clear[j])%n;//將加密後密文放入Ciphertext[]中
                count--;
            }
        }
        System.out.print("所得的密文爲:");
        for(int h=0;h<size;h++)
            System.out.print(Ciphertext[h]);
        System.out.println();
    }
    public void decode(){
        //解密算法
        long count;
        for(int i=0;i<size-1;i++) //(size-1)爲密文實際長度
            decryptionText[i]=1;
        for(int j=0;j<size-1;j++){
            count=this.d; //count表示解密時的次方數
            while(count>0){
                decryptionText[j]=(decryptionText[j]*Ciphertext[j])%n;
                count--;
            }
        }
        System.out.print("解密後明文爲:");
        for(int k=0;k<size-1;k++)
            System.out.print(decryptionText[k]);
        System.out.println();
    }
    public static void main(String[] args)throws Exception{
        RsaUtil t=new RsaUtil();
        t.inputPQ();//輸入兩個素數p、q,計算出n,phi
        t.getPublicKey();//算出公鑰e
        t.getPrivateKey();//算出私鑰d
        t.encryption();//輸入明文,並對明文進行加密
        t.decode();//對密文進行解密
    }
}
 java

相關文章
相關標籤/搜索