1. 程式人生 > >java實現RSA大數乘方取模運算

java實現RSA大數乘方取模運算

        公鑰加密

        公鑰加密,也叫非對稱(金鑰)加密(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是用數學原理巧妙實現的,其實詳細演算法原理可檢視:

      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() + "\n");
     }
     }    

     是不是很巧妙,實際上其計算方式為2^15 = 2*4^7 = 8*16^3 = 16*8*256 ,很快就將乘方變成數次乘法,同時中間乘法過程中加入取模大大減少計算量。