非對稱加密——RSA算法工具類

關於RSA算法的介紹網上一大堆,一句話就是牛B。

package com.demo;

import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAUtils {

    /**
     * 加密(對外暴露)
     * 如果使用 公鑰 對數據 進行加密,只有用對應的 私鑰 才能 進行解密。
     * 如果使用 私鑰 對數據 進行加密,只有用對應的 公鑰 才能 進行解密。
     * @param keyStr
     * @param data
     * @return
     * @throws Exception
     */
    public static String encryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {
        if (StringUtils.isEmpty(keyStr)) {
            return "";
        }
        return encryptBASE64(encrypt(getKey(keyStr, isPublicKey), data.getBytes()));
    }

    /**
     * 解密(對外暴露)
     * 如果使用 公鑰 對數據 進行加密,只有用對應的 私鑰 才能 進行解密。
     * 如果使用 私鑰 對數據 進行加密,只有用對應的 公鑰 才能 進行解密。
     * @param keyStr
     * @param data
     * @return
     * @throws Exception
     */
    public static String decryptData(String keyStr, String data, Boolean isPublicKey) throws Exception {
        if (StringUtils.isEmpty(keyStr)) {
            return "";
        }
        return new String(decrypt(getKey(keyStr, isPublicKey), decryptBASE64(data)), "UTF-8");
    }

    /**
     * 加密
     * @param key
     * @param srcBytes
     * @return
     */
    private static byte[] encrypt(Key key, byte[] srcBytes) {
        if (key != null) {
            try {
                //Cipher負責完成加密或解密工作,基於RSA
                Cipher cipher = Cipher.getInstance("RSA");
                //對Cipher對象進行初始化
                cipher.init(Cipher.ENCRYPT_MODE, key);
                //加密,結果保存進resultBytes,並返回
                return cipher.doFinal(srcBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 解密
     *
     * @param key
     * @param encBytes
     * @return
     */
    private static byte[] decrypt(Key key, byte[] encBytes) {
        if (key != null) {
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                //對Cipher對象進行初始化
                cipher.init(Cipher.DECRYPT_MODE, key);
                //解密並將結果保存進resultBytes
                return cipher.doFinal(encBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根據key獲取公有或者私有key對象
     * @param keyStr
     * @param isPublicKey
     * @return
     * @throws Exception
     */
    private static Key getKey(String keyStr, Boolean isPublicKey) throws Exception {
        if(isPublicKey){
            return getPublicKey(keyStr);
        }else{
            return getPrivateKey(keyStr);
        }
    }

    /**
     * 根據公有key獲取公有key對象
     * @param key
     * @return
     * @throws Exception
     */
    private static RSAPublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPublicKey) keyFactory.generatePublic(keySpec);
    }

    /**
     * 根據私有key獲取私有對象
     * @param key
     * @return
     * @throws Exception
     */
    private static RSAPrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(key);
         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
    }

    /**
     * 獲取公有/私有Key
     * @return
     */
    private static KeyPair getRSAKey() {
        KeyPair keyPair = null;
        try {
            //生成公鑰和私鑰對,基於RSA算法生成對象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            //初始化密鑰對生成器,密鑰大小爲512位
            keyPairGen.initialize(1024);
            //生成一個密鑰對,保存在keyPair中
            keyPair = keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }

    /**
     * 對字符串進行BASE64Decoder
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] decryptBASE64(String key) throws Exception {
        return Base64.getDecoder().decode(key);
    }

    /**
     * 對字節數組進行BASE64Encoder
     * @param key
     * @return
     * @throws Exception
     */
    private static String encryptBASE64(byte[] key) throws Exception {
        return  Base64.getEncoder().encodeToString(key);
    }

    public static void main(String[] args) throws Exception {
        // 生成的一對key保存好
        try {
            //得到私鑰和公鑰
            KeyPair keyPair = getRSAKey();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

            String pubKey = encryptBASE64(publicKey.getEncoded());
            String priKey = encryptBASE64(privateKey.getEncoded());
            System.out.println("公鑰:" + pubKey);
            System.out.println("私鑰:" + priKey);

            // 測試
            String message = "QWERDF";

            System.out.println("明文:" + message);
            String jiami = encryptData(pubKey, message, true);
            System.out.println("公鑰加密後:" + jiami);
            String jiemi = decryptData(priKey, jiami, false);
            System.out.println("用私鑰解密後的結果是:" + jiemi);

            jiami = encryptData(priKey, message, false);
            System.out.println("私鑰加密後:" + jiami);
            jiemi = decryptData(pubKey, jiami, true);
            System.out.println("用公鑰解密後的結果是:" + jiemi);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  

輸出:

公鑰:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw2WgOrzQSnDnVNSFKPyI0FgC+urKg6cSFaAB3KuHo5dM5KQJyjLWas9OSSfGvkfbn9i7APscViTShbu0HbbTVNAIMr29EoReAM1zz4bXMnSmD1Unmks1e05mjXa19BitZnXNyJj6Az9mbkkcdf+u/pH8GQbx0Dp9FLGMP4JjMoQIDAQAB
私鑰:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALDZaA6vNBKcOdU1IUo/IjQWAL66sqDpxIVoAHcq4ejl0zkpAnKMtZqz05JJ8a+R9uf2LsA+xxWJNKFu7QdttNU0Agyvb0ShF4AzXPPhtcydKYPVSeaSzV7TmaNdrX0GK1mdc3ImPoDP2ZuSRx1/67+kfwZBvHQOn0UsYw/gmMyhAgMBAAECgYBkqoxh93cjtMvywjh94+wbS/8Gko2FrSuRaL8DFmTbxp7yZZagD9p8AirHldG+R88NAQRhqBp49s3/qn3AAcGxuMwI7Y82bvEzGqvy/dhjsb3yjmhNcUV9J4mqACL39lz9sn6xmsgvP3omaxrvZZyLZRj1uFfhVD2G9hTzTfxa9QJBAP33lJUvf4hJs7WDR4cRJ0gTAVfHpn9PTURg+oZ7i2qNronOS2+efAn76k4GJ8J95dxpNcHt88fmvTLEzj5FErMCQQCyQ8yS8XMv0p9p6G37y8VwvuOhmxDKZSmFyW5MnDFgnt5nXrcimUeUiWOhjweJgksp7tuuy8Bj71GbeyceT71bAkBzT0ILKnHBM5WAyIZlcQhg1SA69s9F5n+ymEWnYdi/HG0u7Jebql2vOs37dxf+WqNPHAXoc13IWZ91uZ3a8Am5AkALuIN54eA1875Bg2O/230G1bY3yO9Ir3AUeNMEvHxOowNyfnrCDpvzOzlOxQ20z9lLT4YoLwNeTrzp4SYISyvjAkEAzNblWl/dPb+ycxQ6IdGHIOhwweA5QCz7ibx7U154vx1W/sizfIkYKJWo4Nhx8p0SpCXn7FY9jnszVbeNXIdhQw==
明文:QWERDF
公鑰加密後:QLmRoHyM7bepkqhXj/64QEFTMs5eq1L6XeUi0PQorpb4rsWsGV+PW9x/6xbLXeKfXLI6mrS08d6T37wXX9Ww8TWO9ikJuJQdnFnh6M6x9bvfj7KH01W66NoGNInu0rs3wiZpMolL7rFOp6tGOJ8iBJ+tYZSKb8srOxzwtQgc1Zg=
用私鑰解密後的結果是:QWERDF
私鑰加密後:LnS182WnGZ8StGvldATzLtzDnGh+GB02eVYuQvWPO6HbY0qS+prr4UipEQoaKK6JwuX1+C0sX4VxaEYG8UOpIgNKR5LCpHTAOXEaMmrLLO8QZeo9MGBLp3DofAlmWvmqOBzhQVq5DJfp4Oyyt4wVZ5UI8i1HoCc/LplW0NjWLbU=
用公鑰解密後的結果是:QWERDF

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章