淺談RSA加密算法


一、什么是非對稱加密

1、加密的密鑰與加密的密鑰不相同,這樣的加密算法稱之為非對稱加密

2、密鑰分為:公鑰,私鑰

   公鑰:可以對外給任何人的加密和解密的密碼,是公開的

     私鑰:通過私鑰可以生成公鑰,但從公鑰被認為無法生成公鑰(被推導出的概率小到不考慮)

3、當將要加密的內容用公鑰加密的時候,只能用私鑰來解密

     當將要加密的內容用私鑰加密的時候,只能用公鑰來解密

4、公鑰與私鑰的關系,利用一個簡單的公式來生成公鑰和私鑰,即非對稱加密的公鑰和私鑰之間存在某一個公式關系

5、常見的非對稱加密算法

  RSA,DSA


二、什么是RSA算法

RSA算法是一種非對稱密碼算法,所謂非對稱,就是指該算法需要一對密鑰,使用其中一個加密,則需要用另一個才能解密。
RSA的算法涉及三個參數,n、e1、e2。
其中,n是兩個大質數p、q的積,n的二進制表示時所占用的位數,就是所謂的密鑰長度。
e1和e2是一對相關的值,e1可以任意取,但要求e1與(p-1)*(q-1) 互質;再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。
(n,e1),(n,e2)就是密鑰對。其中(n,e1)為 公鑰,(n,e2)為私鑰。[1]  
RSA加解密的算法完全相同,設A為明文,B為密文,則:A=B^e2 mod n;B=A^e1 mod n;(公鑰加密體制中,一般用公鑰加密,私鑰解密)
e1和e2可以互換使用,即:
A=B^e1 mod n;B=A^e2 mod n;
 
三、RSA加密算法的使用
1、RSA密鑰的生成,返回一個KeyPair對象
KeyPair 用於非對稱加密,KeyPair中包含了一個公鑰和一個私鑰
    /**
     * 通過指定的密鑰長度生成非對稱的密鑰對
     * @param keySize  推薦使用1024,2048 ,不允許低於1024
     * @return
     */
    public static KeyPair generateRSAKeyPair(int keySize){
        KeyPair ret = null;
        try {
            //1、准備生成
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
            //2、初始化,設置秘鑰長度
            generator.initialize(keySize);
            //3、生成,並且返回
            ret = generator.generateKeyPair();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return ret;
    }

 

2、獲取私鑰和公鑰

PublicKey 和 PrivateKey 都是Key類型的

     KeyPair keyPair = EncryptUtil.generateRSAKeyPair(1024);
        //獲取公鑰,可以給任何人
        PublicKey publicKey = keyPair.getPublic();
     //獲取私鑰 PrivateKey privateKey
= keyPair.getPrivate();

 

3、RSA加密

/**
     *  RSA 加密
     * @param data  需要加密的數據
     * @param key  可以是 PublicKey,也可以是PrivateKey
     * @return
     */
    public static byte[] rsaEncrypt(byte[] data ,Key key){
        byte[] ret = null;
        if (data != null
                && data.length>0
                && key!=null) {
            // 1、創建Cipher 使用RSA
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                //設置Key
                cipher.init(Cipher.ENCRYPT_MODE,key);
                ret = cipher.doFinal(data);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

 

4、RSA解密

/**
     *  RSA 解密
     * @param data 要解密的數據
     * @param key  可以是 PublicKey,也可以是PrivateKey
     * @return
     */
    public static byte[] rsaDecrypt(byte[] data ,Key key){
        byte[] ret = null;

        if (data != null
                && data.length>0
                && key!=null) {
            // 1、創建Cipher 使用RSA
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                //設置Key
                cipher.init(Cipher.DECRYPT_MODE,key);
                ret = cipher.doFinal(data);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

 

5、公鑰與私鑰的存儲

一對公鑰和私鑰創建好之后,我們需要存儲起來以后使用

    //獲得公鑰 私鑰
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();
        //編碼將PublicKey和PrivateKey對象轉換為字節數組,該字節數組為公鑰、私鑰的實際數據
        byte[] publicKeyEncoded = publicKey.getEncoded();
        byte[] privateKeyEncoded = privateKey.getEncoded();
     //將字節數組通過Base64編碼算法 編碼成可見的字符形式 String publickey
= Base64.encodeToString(publicKeyEncoded, Base64.NO_WRAP); String privatekey = Base64.encodeToString(privateKeyEncoded, Base64.NO_WRAP);
     //進行存儲操作
     。。。。

 

6、公鑰與私鑰的加載

通常 1、獲取密鑰對 2、獲取公鑰、私鑰 3、保存公鑰、私鑰,保存形式基本為字符串形式

那么在以后的使用中就需要獲取公鑰和私鑰來使用

需要知道:

  6.1、KeyFactory可以來加載相應的公鑰和私鑰

  6.2、公鑰加載 使用 X509EncodedKeySpec(byte[])

  6.3、私鑰加載 使用 PCKS8EncodedKeySpec(byte[])

//獲取公鑰
//str_publickey 為公鑰字符串形式數據(公鑰先編碼成byte[] 在 形成字符串)
//解碼
            byte[] publicdecode = Base64.decode(new String(str_publickey), Base64.NO_WRAP);
            //構造X509EncodedKeySpec對象
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicdecode);
            //指定加密算法
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            //取得公鑰
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
//解碼
//獲取私鑰
//str_private 為私鑰字符串形式的數據 byte[] privatedecode = Base64.decode(new String(str_private), Base64.NO_WRAP); //構造X509EncodedKeySpec對象 PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privatedecode); //指定加密算法 keyFactory = KeyFactory.getInstance("RSA"); //取得私鑰 PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

 

相關知識:

淺談DES加密算法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM