RSA加解密算法的过程很简单,它是典型的公钥加密算法,算法简单明了是较典型对称加密算法DES而言!

RSA加解密算法过程大致如下:

首先:选择两个大素数(通常都在百位以上才能保证足够安全)P,Q;

接着:计算P*Q=N,(P-1)*(Q-1)=fn;

接着:随机选择一个数E(其实为了安全要保证它也足够大,但要小于fn),使其满足E和fn的最大公因子为1,就是满足它倆互质,这样的E就是可以充当公钥了;

接着:计算私钥,私钥D满足公式(E*D)%fn=1,满足该公式的D可以充当私钥;

最后:加密是,明文W,加密公式是求W的E次方和N的余数,解密公式是求前面加密得到的余数的D次方和N的余数!(为了保证正确性要使得W要小于N)

接下来就是我用java实现了一个极其简单的RSA算法:

makekey.java实现选择俩素数,确定公私钥

import java.util.Random;
 public class makekey {
 private static int P,Q,D,E,FN;
 static Random rdom=new Random();
     public static void twopnumcre(){
      setp(cheackp());//设置素数p
      setq(cheackp());//设置素数q
     }
     public static int cheackp(){//获得一个素数,本例中为了计算正确将两个大素数控制在13以内
      int num=rdom.nextInt(13);
      while(true){
       boolean is=true;
       for(int h=2;h<num;h++)
        if(num%h==0)
        {
         is=false;
               break;
        }
       if(num==1||num==0)
        is=false;
       if(is)
        break;
       num=rdom.nextInt(13);
      }
      return num;
     }
  public static void pubkeycre(int P,int Q){//得到公钥和私钥
   int fN=(P-1)*(Q-1);
   creE();
   creD(fN,gete());
   setfn();//设置N,N=p*q
   System.out.println("OK!");///表明素数的选择以及公私钥的生成成功
  }
  public static boolean findgyz(int num,int fn){//判断num和fn的最大公因子是否为1,利用到了欧几里得算法判断一个随机生成的数是否可以为公钥
   int a=0;
   while(num>0){
    a=num;
    num=fn%num;
    fn=a;
   }
   if(a==1)
    return true;
   return false;
  }
  public static void creE(){//生成公钥的逻辑
   int num=rdom.nextInt(getFN());//限制公钥的范围在(p-1)*(q-1)以内,超出的话会出错
   while(true){
    
    if(findgyz(num,getFN())&&num!=1){
     sete(num);
     break;
    }
   num=rdom.nextInt(getFN());
   }
  }
  public static void creD(int fn,int e){//公钥选好后计算得到私钥
   int num=1;
   while(true){
    if((num*fn+1)%e==0)
    {
     setd((num*fn+1)/e);
     break;
    }
    num++;
   }
  }
  public static void setp(int p){
   P=p;
  }
  public static void setq(int q){
   Q=q;
  }
  public static void setd(int d){
   D=d;
  }
  public static void sete(int e){
   E=e;
  }
  public static int getp(){
   return P;
  }
  public static int getq(){
   return Q;
  }
  public static int getd(){
   return D;
  }
  public static int gete(){
   return E;
  }
  public static void setfn(){
   FN=P*Q;
  }
  public static int getfn(){
   return FN;
  }
  public static int getFN(){
   return (P-1)*(Q-1);
  }
 }

jiajiesic.java是程序的入口:

import java.util.Scanner;
 public class jiajiesic {
  Scanner scan=new Scanner(System.in);
  public jiajiesic(){
   makekey.twopnumcre();//先得到两个素数
   makekey.pubkeycre(makekey.getp(), makekey.getq());//生成公私钥
   System.out.println("选择的两个素数是:"+makekey.getp()+"\t"+makekey.getq());
   System.out.println("公钥、私钥以及N分别是:"+makekey.gete()+"\t"+makekey.getd()+"\t"+makekey.getfn());
   String str="9";
   int tempsic,tempming;
   System.out.println("请输入要加密的字符串('0'退出)!");
   while(str.charAt(0)!='0'){
   str=scan.nextLine();
   tempsic=jiasic(Integer.parseInt(str));??
   tempming=jiesic(tempsic);
   System.out.println("加密后是:"+tempsic);
   
   System.out.println("解密后是:"+tempming);
   
   }
  }
 public int jiasic(int num){//加密
  return (int)Math.pow(num,makekey.gete())%makekey.getfn();
 }
 public int jiesic(int num){//解密
  return (int)Math.pow(num, makekey.getd())%makekey.getfn();
 }
  /**
   * @param args
   */
  public static void main(String[] args) {
   // TODO Auto-generated method stub
   new jiajiesic();
  }}

从我的实现可以看出俩素数的选择违背了RSA的要求,但百位以上的素数的判定以及计算都是很困难的,至少对我来说是这样;还有就是在加解密的过程中是直接调用java.math的求方公式,是死算,没有加点技巧保证求方时不溢出,在遇到大的数时会计算溢出导致结果不正确,所以验证时也最好选择20以内的数验证,有时20以内的数计算也会溢出!

正确运行结果如下:

c 加密 java解密rsa java实现rsa加密解密_加解密