RSA 算法原理

 

<一>基础

RSA算法非常简单,概述如下:
找两素数p和q
取n=p*q
取t=(p-1)*(q-1)
取任何一个数e,要求满足e<t并且e与t互素(就是最大公因数为1)
取d*e%t==1

(其中,公钥的exponent即RSA算法中的e, e通常是3,17和65537
X.509建议使用65537,PEM建议使用3,PKCS#1建议使用3或65537,一般来说,都是选择3。)

这样最终得到三个数: n  d  e

 


设消息为数M (M <n)
设c=(M**d)%n就得到了加密后的消息c
设m=(c**e)%n则 m == M,从而完成对c的解密。
注:**表示次方,上面两式中的d和e可以互换。

在对称加密中:
n e两个数构成公钥,可以告诉别人;
n d两个数构成私钥,d自己保留,不让任何人知道。
给别人发送的信息使用d加密,只要别人能用e解开就证明信息是由你发送的
别人给你发送信息时使用e加密,这样只有拥有d的你能够对其解密。



rsa的安全性在于对于一个大数n,没有有效的方法能够将其分解
从而在已知n d的情况下无法获得e;同样在已知n e的情况下无法
求得d。

 


以上原理详见维基百科:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95#.E5.85.AC.E9.92.A5.E5.92.8C.E7.A7.81.E9.92.A5.E7.9A.84.E4.BA.A7.E7.94.9F


<二>实践

Java代码 复制代码  收藏代码
  1. package com.yajun.rsa;   
  2.   
  3. import java.io.Serializable;   
  4. import java.math.BigInteger;   
  5. import java.security.SecureRandom;   
  6.   
  7. /**  
  8.  * RSA 算法原理实现  
  9.  *   
  10.  * @author Administrator  
  11.  */  
  12. public class RSA implements Serializable {   
  13.     private static final long         serialVersionUID = 7935341891569534021L;   
  14.   
  15.     private final static BigInteger   one              = BigInteger.ONE;   
  16.     private final static SecureRandom random           = new SecureRandom();   
  17.     private BigInteger                privateKey       = null;   
  18.     private BigInteger                publicKey        = null;   
  19.     private BigInteger                modulus          = null;   
  20.     private BigInteger                p1               = null;   
  21.     private BigInteger                p2               = null;   
  22.     //Ces variables doivent être initialisé pour l'encrytage de données.   
  23.     private BigInteger                modulusE;   
  24.     private BigInteger                publicKeyE;   
  25.     private int                       N;   
  26.     private BigInteger                phi0;   
  27.   
  28.     public RSA(int N) {   
  29.         this.N = N;   
  30.         // generate an N-bit (roughly) public and private key   
  31.         //clés privé   
  32.         //p1   
  33.         p1 = BigInteger.probablePrime(N / 2, random);   
  34.         //p2   
  35.         p2 = BigInteger.probablePrime(N / 2, random);   
  36.         //t   
  37.         phi0 = (p1.subtract(one)).multiply(p2.subtract(one));   
  38.         //n   
  39.         modulus = p1.multiply(p2);   
  40.         //d   
  41.         setPrivateKey();   
  42.         //e   
  43.         publicKey = privateKey.modInverse(phi0);   
  44.         modulusE = modulus;   
  45.         publicKeyE = publicKey;   
  46.     }   
  47.   
  48.     public BigInteger getModulus() {   
  49.         return modulus;   
  50.     }   
  51.   
  52.     public BigInteger getPublicKey() {   
  53.         return publicKey;   
  54.     }   
  55.   
  56.     public void setPublicKey(BigInteger p, BigInteger n) {   
  57.         publicKeyE = p;   
  58.         modulusE = n;   
  59.     }   
  60.   
  61.     /**  
  62.      * 这部分没怎么看懂  
  63.      */  
  64.     private void setPrivateKey() {   
  65.         do {   
  66.             privateKey = BigInteger.probablePrime(N / 2, random);   
  67.         } while (privateKey.gcd(phi0).intValue() != 1 || privateKey.compareTo(modulus) != -1  
  68.                 || privateKey.compareTo(p1.max(p2)) == -1);   
  69.     }   
  70.   
  71.     /**  
  72.      * 加密  
  73.      *   
  74.      * @param message  
  75.      * @return  
  76.      */  
  77.     public BigInteger encrypt(BigInteger message) {   
  78.         BigInteger rep = null;   
  79.         String str_message = new String(message.toByteArray());   
  80.         if (message != null) {   
  81.             if (str_message.length() <= (N / 8)) {   
  82.                 if (publicKeyE != null && modulusE != null  
  83.                         && message.toByteArray().length < Integer.MAX_VALUE) {   
  84.                     rep = message.modPow(publicKeyE, modulusE);   
  85.                 }   
  86.             }   
  87.         }   
  88.         return rep;   
  89.     }   
  90.   
  91.     /**  
  92.      * 加密,公式比较容易看懂  
  93.      *   
  94.      * @param message  
  95.      * @param publicKeyP  
  96.      * @param modulusP  
  97.      * @return  
  98.      */  
  99.     public BigInteger encrypt(BigInteger message, BigInteger publicKeyP, BigInteger modulusP) {   
  100.         BigInteger rep = null;   
  101.         String str_message = new String(message.toByteArray());   
  102.         if (str_message.length() <= (N / 8)) {   
  103.             if (publicKeyP != null && modulusP != null  
  104.                     && message.toByteArray().length < Integer.MAX_VALUE) {   
  105.                 rep = message.modPow(publicKeyP, modulusP);   
  106.             }   
  107.         }   
  108.         return rep;   
  109.     }   
  110.   
  111.     /**  
  112.      * 解密,公式也比较容易看懂  
  113.      *   
  114.      * @param encrypted  
  115.      * @return  
  116.      */  
  117.     public BigInteger decrypt(BigInteger encrypted) {   
  118.         return encrypted.modPow(privateKey, modulus);   
  119.     }   
  120.   
  121.     public String toString() {   
  122.         String s = "";   
  123.         s += "public  = " + publicKey + "\n";   
  124.         s += "modulus = " + modulus;   
  125.         return s;   
  126.     }   
  127.   
  128.     public static void main(String[] args) {   
  129.         BigInteger message = BigInteger.valueOf(88);   
  130.         RSA rsa = new RSA(512);   
  131.         BigInteger enInteger = rsa.encrypt(message);   
  132.         BigInteger deInteger = rsa.decrypt(enInteger);   
  133.         System.out.println(enInteger);   
  134.         System.out.println(deInteger);   
  135.     }   
  136. }  
package com.yajun.rsa;

import java.io.Serializable;
import java.math.BigInteger;
import java.security.SecureRandom;

/**
 * RSA 算法原理实现
 * 
 * @author Administrator
 */
public class RSA implements Serializable {
    private static final long         serialVersionUID = 7935341891569534021L;

    private final static BigInteger   one              = BigInteger.ONE;
    private final static SecureRandom random           = new SecureRandom();
    private BigInteger                privateKey       = null;
    private BigInteger                publicKey        = null;
    private BigInteger                modulus          = null;
    private BigInteger                p1               = null;
    private BigInteger                p2               = null;
    //Ces variables doivent être initialisé pour l'encrytage de données.
    private BigInteger                modulusE;
    private BigInteger                publicKeyE;
    private int                       N;
    private BigInteger                phi0;

    public RSA(int N) {
        this.N = N;
        // generate an N-bit (roughly) public and private key
        //clés privé
        //p1
        p1 = BigInteger.probablePrime(N / 2, random);
        //p2
        p2 = BigInteger.probablePrime(N / 2, random);
        //t
        phi0 = (p1.subtract(one)).multiply(p2.subtract(one));
        //n
        modulus = p1.multiply(p2);
        //d
        setPrivateKey();
        //e
        publicKey = privateKey.modInverse(phi0);
        modulusE = modulus;
        publicKeyE = publicKey;
    }

    public BigInteger getModulus() {
        return modulus;
    }

    public BigInteger getPublicKey() {
        return publicKey;
    }

    public void setPublicKey(BigInteger p, BigInteger n) {
        publicKeyE = p;
        modulusE = n;
    }

    /**
     * 这部分没怎么看懂
     */
    private void setPrivateKey() {
        do {
            privateKey = BigInteger.probablePrime(N / 2, random);
        } while (privateKey.gcd(phi0).intValue() != 1 || privateKey.compareTo(modulus) != -1
                || privateKey.compareTo(p1.max(p2)) == -1);
    }

    /**
     * 加密
     * 
     * @param message
     * @return
     */
    public BigInteger encrypt(BigInteger message) {
        BigInteger rep = null;
        String str_message = new String(message.toByteArray());
        if (message != null) {
            if (str_message.length() <= (N / 8)) {
                if (publicKeyE != null && modulusE != null
                        && message.toByteArray().length < Integer.MAX_VALUE) {
                    rep = message.modPow(publicKeyE, modulusE);
                }
            }
        }
        return rep;
    }

    /**
     * 加密,公式比较容易看懂
     * 
     * @param message
     * @param publicKeyP
     * @param modulusP
     * @return
     */
    public BigInteger encrypt(BigInteger message, BigInteger publicKeyP, BigInteger modulusP) {
        BigInteger rep = null;
        String str_message = new String(message.toByteArray());
        if (str_message.length() <= (N / 8)) {
            if (publicKeyP != null && modulusP != null
                    && message.toByteArray().length < Integer.MAX_VALUE) {
                rep = message.modPow(publicKeyP, modulusP);
            }
        }
        return rep;
    }

    /**
     * 解密,公式也比较容易看懂
     * 
     * @param encrypted
     * @return
     */
    public BigInteger decrypt(BigInteger encrypted) {
        return encrypted.modPow(privateKey, modulus);
    }

    public String toString() {
        String s = "";
        s += "public  = " + publicKey + "\n";
        s += "modulus = " + modulus;
        return s;
    }

    public static void main(String[] args) {
        BigInteger message = BigInteger.valueOf(88);
        RSA rsa = new RSA(512);
        BigInteger enInteger = rsa.encrypt(message);
        BigInteger deInteger = rsa.decrypt(enInteger);
        System.out.println(enInteger);
        System.out.println(deInteger);
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值