java实现RSA大数乘方取模运算

2019-04-13 13:02发布

        公钥加密
        公钥加密,也叫非对称(密钥)加密(public key encryption),属于通信科技下的网络安全二级学科,指的是由对应的一对唯一性密钥(即公开密钥和私有密钥)组成的加密方法。它解决了密钥的发布和管理问题,是目前商业密码的核心。其特点是1,加密和解密算法都是公开的;2,所有公钥加密的数据只有用私钥才能够解开,用公钥自己解不开;3用私钥加密的数据,只有用公钥才能解开,用私钥也解不开;4加密和解密算法都是公开的,受限于计算机的运算速度,用公钥不能破解出私钥。         RSA算法         实现公私钥这几个要求的算法有很多,如RSA、ElGamal、背包算法、Rabin(Rabin的加密法可以说是RSA方法的特例)、Diffie-Hellman (D-H) 密钥交换协议中的公钥加密算法、Elliptic Curve Cryptography(ECC,椭圆曲线加密算法)。使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开金钥加密算法。RSA加减密用的是同样的算法
     EmodN         DmodN
       公钥私钥中都包含有N,而且这个N是相同的,假如服务方加密的时候,使用私钥E加密,拿到公钥的人,都可以使用公钥D进行解密。相反的过程更有意义,你回复服务方的时候使用公钥加密,这时候只有拥有私钥的服务方才能解密,其他拥有公钥的人是不能解密的,这样保证了客户发往服务方数据的安全性。        公钥和私钥的生成算法        RSA是用数学原理巧妙实现的,其实详细算法原理可查看:        1,RSA算法原理一(阮一峰)        2,RSA算法原理二(阮一峰)
       3,   RSA辅助工具,用来生成对称的公私钥大数
      java实现大数乘方取模       根据上面的RSA算法,要实现对数据要进行乘方取模,计算量还是非常大的,如果是硬乘方,估计1个32位的数据加密都需要等很长时间,好在通过数学同模定理可以减少很多计算量,如下:       (A^E)%N = ((A%N)^E)%N       (A*B)%N = ((A%N)*(B%N)) %N      (7^10000)%6 = ((7%6)^10000)%6 = (1^10000)%6 = 1 是不是计算量大大减少了。      很有意思的,我们发现7的任意次方模6总是等于1,如7, 49;同样的,8的任意次方模7总等于1,而9的任意次方模8总等于1,因为同模定理,以及1的任意次方总等于1。      好吧,直接上java代码来实现乘方取模:      import java.math.BigInteger;
     import java.math.*;
     import java.util.*;

     public class Test {

     public static void main(String[] args) {
        BigInteger result = new BigInteger("1");
        BigInteger temp= new BigInteger("80826029221689");
        BigInteger k1= new BigInteger("82006849731579");
        BigInteger m= new BigInteger("194766297404401");
        while (k1.compareTo(new BigInteger("0")) > 0){
                if (k1.mod(new BigInteger("2")).intValue() == 1) {
                        result = (result.multiply(temp)).mod(m);
                }
                temp = (temp.multiply(temp)).mod(m);
                k1 = k1.divide(new BigInteger("2"));
        }
        System.out.println(result.toString() + " ");
     }
     }    
     是不是很巧妙,实际上其计算方式为2^15 = 2*4^7 = 8*16^3 = 16*8*256 ,很快就将乘方变成数次乘法,同时中间乘法过程中加入取模大大减少计算量。