rsa加解密 用java浅谈有demo

快要闲的被开除了 所以我决定做些其他事加速我程序生涯的结束
翻到rsa算法 发现物理是神的学科 数学是成神之前的学科
为寻其原理(为自己写个简单demo)搜了一下
有这个网址这个网址说的比较好(对于我这种一点都没了解过的)
=========
rsa的内涵在于公私钥的加解密
http中是明文传输,https中ssl就有用到类似的公私钥外加证书认证做到保密。
==========
rea加解密过程
注:≡是同余数的意思 比如 1≡3 mod 2 成立,1和3% 2都是1下面有de≡1 mod f(n)
(1)选择一对不同的、足够大的素数p,q。
(2)计算n=pq。
(3)计算f(n)=(p-1)(q-1),同时对p, q严加保密,不让任何人知道。
(4)找一个与f(n)互质的数e,且1<e<f(n)。
(5)计算d,使得de≡1 mod f(n)。这个公式也可以表达为d ≡e-1 mod f(n)
这里要解释一下,≡是数论中表示同余的符号。公式中,≡符号的左边必须和符号右边同余,也就是两边模运算结果相同。显而易见,不管f(n)取什么值,符号右边1 mod f(n)的结果都等于1;符号的左边d与e的乘积做模运算后的结果也必须等于1。这就需要计算出d的值,让这个同余等式能够成立。
(6)公钥KU=(e,n),私钥KR=(d,n)。
(7)加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。设密文为C,则加密过程为:
(8)解密过程为:。 
(1)选择一对不同的、足够大的素数p,q。
int p = 997 ,q = 1009 ;
 这个刚好是1000000多点 验证码或银行密码的6位数能放进去。。。
(2)计算n=pq。
int n = p*q;//p*q
(3)计算f(n)=(p-1)(q-1),同时对p, q严加保密,不让任何人知道。
int fn = (p-1)*(q-1); //(p-1)*(q-1);
(4)找一个与f(n)互质的数e,且1<e<f(n)。
int e =  Util.getCoprimeList(fn);//93733 ;//Util.getCoprimeList(fn);
   原谅我搞android的习惯性工具函数类放一个Util.java里
 //返回一个小点的互质数
    public static int getCoprimeList(int num){
        int coprime = 3;
        for( ;coprime <= num ;coprime++){
            if(check2(num,coprime))
                return coprime;
        }
        return 1;
    }
    //判断是否互质
    public boolean check(int m, int n)
    {
        return check2(m > n ? m : n, m <= n ? m : n);
    }
    public static boolean check2(int max, int min)
    {
        int mo = max % min;
        Log.e("ssh",max + "  "+ min);
        if (mo == 0) {
            return min == 1 ? true : false;
        }
        else {
            return check2(min, mo);
        }
    }
 本来设置互质数从随机中间数开始找 结果运算就爆炸了 管他的小点就小点
(5)计算d,使得de≡1 mod f(n)。这个公式也可以表达为d ≡e-1 mod f(n)

  本来看到这个一下懵逼了,搜了同余是什么 同余怎么求解 上面给的第二个链接教我了解决方法  成神前的数学
  网页中给的demo里f(n)=(p-1)(q-1)= 18442 × 49890= 920071380  e = 19,求d 
 d满足:e * d ≡ 1 (mod f(n)) 
  即(19 * d) mod 920071380 = 1 
  欧几里德算法(辗转相除法)求d

 循环,直至d 的系数为 1, 即e位置=1时结束

[a式]19×d - 920071380×k =1      (k 为正整数)
[b式]19×d - 9×k =1f(n)位置 mod e位置 的余数9代替f(n)位置
[c式]1×d - 9×k=1e位置 mod f(n)位置 的余数1代替e位置
e位置=1,结束,然后 
 令k=0,带入[c式],得d=1; 
 d=1,带入[b式],得k=2; 
 k=2,带入[a式],得d=96849619 
 到这里求出d值了
于是就有了我自己的破算法

int d = Util.getD(e,fn);
//求d
    public static int getD(int e , int fn){
        int k = 1, d = 1;
        ArrayList<Integer> eList = new ArrayList();
        ArrayList<Integer> fnList = new ArrayList();
        eList.add(e);
        fnList.add(fn);
        boolean trueOrFalse = true;
        while (e != 1 && fn != 1){
            if(trueOrFalse){
                fn = fn % e;
                trueOrFalse = false;
            }
            else{
                e = e % fn;
                trueOrFalse = true;
            }
            eList.add(e);
            fnList.add(fn);
        }

        for (int i = eList.size()-1 ; i >= 0 ; i--){
            if(i%2 == 0){
                d = (fnList.get(i)*k+1)/eList.get(i);
            }
            else{
                k = (eList.get(i)*d-1)/fnList.get(i);
            }
        }
        return d;
    }
(6)公钥KU=(e,n),私钥KR=(d,n)。

 然后就能得到我们自己的 我demo得到的 e=5 n=1005973 d=602381
(7)加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。设密文为C,则加密过程为:

话说这步真的很麻烦被加密的m必须小于n   太长就要分割 (要传汉字基本可以一个字一个字加密了)  而且e次方绝对会超过java 的int,long上限 原先我互质数e设为从中间随机去查找几万都出来了 妥妥的超过double。就按时间复杂度最差的写了递归函数(因为我省事不用想啊)

int mima = 333333;
int c = (int) Util.getC(mima,e,n);
// 加密过程为:C≡M^e(mod n)。
    public static double getC(double M, int e ,int n){
        //10 3 33
        int i = 1;
        double mod = M;
        while ( i< e ){
            mod = (mod*M)%n;
            i++;
        }
        return mod;

    }
(8)解密过程为: 。 

 

int M = (int) Util.getC(c,d,n);//(int) (Math.pow(c,d)%n);
 我的控制台打印结果 (没人发现我用的androidstudio吧)

需要不同公钥私钥只要改变互质数e 或素数p,q(这个改了e也改了)

有大佬有更好的算法见解欢迎留言

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值