天天看點

【Java工具類】非對稱加密之RSA算法工具類

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;
import java.util.HashMap;
import java.util.Map;

/**
 * 非對稱加密RSA算法工具類
 */
public class RSACoder {
    //非對稱密鑰算法
    public static final String KEY_ALGORITHM = "RSA";
    /**
     * RSA密鑰長度必須是64的倍數,在512~65536之間。預設是1024
     */
    public static final int KEY_SIZE = 2048;

    //公鑰
    private static final String PUBLIC_KEY = "publicKey";

    //私鑰
    private static final String PRIVATE_KEY = "privateKey";


    /**
     * 初始化密鑰對
     *
     * @return Map 甲方密鑰的Map
     */
    public static Map<String, Object> initKey() throws Exception {
        //執行個體化密鑰生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);

        //初始化密鑰生成器
        keyPairGenerator.initialize(KEY_SIZE);

        // 生成一個密鑰對,儲存在keyPair中
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        //甲方公鑰
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        System.out.println("系數:" + publicKey.getModulus() + "  加密指數:" + publicKey.getPublicExponent());

        //甲方私鑰
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        System.out.println("系數:" + privateKey.getModulus() + "解密指數:" + privateKey.getPrivateExponent());

        //将密鑰存儲在map中
        Map<String, Object> keyMap = new HashMap<String, Object>();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;

    }



    /**
     * 公鑰加密
     *
     * @param data 待加密資料
     * @param key  密鑰
     * @return byte[] 加密資料
     */
    public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {

        //執行個體化密鑰工廠
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公鑰
        //密鑰材料轉換
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        //産生公鑰
        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);

        //資料加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 私鑰解密
     *
     * @param data 待解密資料
     * @param key  密鑰
     * @return byte[] 解密資料
     */
    public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        //取得私鑰
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私鑰
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //資料解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }


    /**
     * 私鑰加密
     *
     * @param data 待加密資料
     * @param key  密鑰
     * @return byte[] 加密資料
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        //取得私鑰
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成私鑰
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //資料加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公鑰解密
     *
     * @param data 待解密資料
     * @param key  密鑰
     * @return byte[] 解密資料
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {

        //執行個體化密鑰工廠
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公鑰
        //密鑰材料轉換
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        //産生公鑰
        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
        //資料解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 取得私鑰
     *
     * @param keyMap 密鑰map
     * @return byte[] 私鑰
     */
    public static byte[] getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }

    /**
     * 取得公鑰
     *
     * @param keyMap 密鑰map
     * @return byte[] 公鑰
     */
    public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //初始化密鑰
        //生成密鑰對
        Map<String, Object> keyMap = RSACoder.initKey();

        //公鑰
        byte[] publicKey = RSACoder.getPublicKey(keyMap);
        System.out.println("\n公鑰:" +  Base64.getEncoder().withoutPadding().encodeToString(publicKey));//由于加密後的密文都是位元組碼形式的,我們要以字元串方式儲存或傳輸的話,可以使用Base64編碼。
        //私鑰
        byte[] privateKey = RSACoder.getPrivateKey(keyMap);
        System.out.println("\n私鑰:" + Base64.getEncoder().withoutPadding().encodeToString(privateKey));//由于加密後的密文都是位元組碼形式的,我們要以字元串方式儲存或傳輸的話,可以使用Base64編碼。


        System.out.println("\n===========1.公鑰加密,私鑰解密==============");
        String str = "aattaggcctegthththfef/aat.mp4";
        System.out.println("原文:" + str);

        //使用公鑰進行資料的加密
        byte[] code1 = RSACoder.encryptByPublicKey(str.getBytes(), publicKey);
        System.out.println("公鑰加密後的資料:" +   Base64.getEncoder().withoutPadding().encodeToString(code1));
        //使用私鑰進行資料的解密
        byte[] decode1 = RSACoder.decryptByPrivateKey(code1, privateKey);
        System.out.println("私鑰解密後的資料:" + new String(decode1));


        System.out.println("\n===========2.反向進行操作,私鑰加密,公鑰解密==============");
        str ="4b9d373bed9f40b389f0e42ebaf729b4";
        System.out.println("原文:" + str);

        //使用私鑰進行資料的加密
        byte[] code2 = RSACoder.encryptByPrivateKey(str.getBytes(), privateKey);
        System.out.println("私鑰加密後的資料:" +Base64.getEncoder().withoutPadding().encodeToString(code2));
        //使用公鑰進行資料的解密
        byte[] decode2 = RSACoder.decryptByPublicKey(code2, publicKey);
        System.out.println("公鑰解密後的資料:" + new String(decode2));
    }
}
           

main方法執行結果

系數:25673086491181252696735907678323359012290479118460249182240942943781022994992575396590727636402349564925636011579483415535025350805322419881144350331454228457159864635273352797075670117225640053564150779878581672826043466730442466562220815297498994632148250863062496794801485613090601179615469513565622072320713419491283100791224145056532853893350394503766393820017518906472919715328843855105481040100067458333759790298618468832658166599809135248953553073655427587148287992213804301398790107769457487285016468303621342838245142810915126734720967207513720464121646170199288480519720222247070607912244425592472384699833  加密指數:65537
系數:25673086491181252696735907678323359012290479118460249182240942943781022994992575396590727636402349564925636011579483415535025350805322419881144350331454228457159864635273352797075670117225640053564150779878581672826043466730442466562220815297498994632148250863062496794801485613090601179615469513565622072320713419491283100791224145056532853893350394503766393820017518906472919715328843855105481040100067458333759790298618468832658166599809135248953553073655427587148287992213804301398790107769457487285016468303621342838245142810915126734720967207513720464121646170199288480519720222247070607912244425592472384699833解密指數:5951226482353870194986220142043249921642994930613975396746943027632044514395337067992223236526305668406400388908792163950258710795954318977590444637921367147125633818134378682166922203043958736190954402061666124076067753277825990692483003890925808725629739339787378905147079808872429514941456167509787303701594458366179085655994722382066825611874856877831944821823855957870861590255730073317554239720440140157947209450604893997531142179043822700188495148788044375693219726672614185030409346413260290559526517250002718058539432864497234239894526319410363940220217629293027556378044752569803302642220451834422341413473

公鑰:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy165kj4sGDx2rtzHZmTrA++C7LiCX8j7J0OI0MwnLSDp1lNaVsrBU0u1UNHuaKAXzAvDZI8U1rm6cHfh9AhCePNTY2JwCTwf/Xnj1/S7OreIpxxaGuRbnVwCcFbDQ/S8JSpD4bYe5LrkKk1WW15tA6ZaLq1gcbfgRw3ZCB5wkqI4T7jrapS2uNpeGYKdXYRCwArlPSTr3UB33IKA4DXVzE0Gop97GJ4lT+HeewfBUQ7rkIOMka85NL+yi0yB34kHX4uqaySMWe4edNXGJDC1lRxCYTo7QBPBSqS5ibeHpn8Z3RRiYpWRv0UkC75FUyN3yudUhBDAKoOdIuiF2+H9uQIDAQAB

私鑰:MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDLXrmSPiwYPHau3MdmZOsD74LsuIJfyPsnQ4jQzCctIOnWU1pWysFTS7VQ0e5ooBfMC8NkjxTWubpwd+H0CEJ481NjYnAJPB/9eePX9Ls6t4inHFoa5FudXAJwVsND9LwlKkPhth7kuuQqTVZbXm0DplourWBxt+BHDdkIHnCSojhPuOtqlLa42l4Zgp1dhELACuU9JOvdQHfcgoDgNdXMTQain3sYniVP4d57B8FRDuuQg4yRrzk0v7KLTIHfiQdfi6prJIxZ7h501cYkMLWVHEJhOjtAE8FKpLmJt4emfxndFGJilZG/RSQLvkVTI3fK51SEEMAqg50i6IXb4f25AgMBAAECggEALySOL/BpmFSrzm0va/UI5ain2OgMkNeuILPvCzfH/RYcHqrDzkrB9eUe6tU/RtGVsp8ndDAWzI/RQDEKF9+ySQde1TMEdZ+SatfOkUkR/dJ9wv83g/RbqGajyhbSvPYGhzb89V2aW7tXGNdEpXmGG8p8LUXTjYjqXI5BOTiVL+gwvx4eEpgpNzpfKdySyCkpvxuznIqxdvp2w4EZ4Ic9zvhSntCDclAvtjRs/mJClWyx+Fr/JrBhZ/FtMdE4nfyacdjgKA4ubtwz4clEsw7eAMIqksGx8RAv9DvPp1362z3EZpYjuXxZuh9uI7T/uH2u5efL8H8m6BNBMGPHbiQqYQKBgQD2EBKDPDIPG4WyfJxrGoy6B2VI9lOHJnkV5imlfTEBKd/SozjsU5CthvyaisPqjJiq8DiJUtLJT0XT4uoqA1RDoicwUe+MeKBwlPHcnJno/jO8cDtimBalpHivExnnRA5Og+ES82HV2qcFnTTrdKVbnHaKEQzwLegFMM56mJQ4GwKBgQDTlUWpjQzaUAaCSlV4JaWscNZdc7zNKW8fIcHql7W5+QEx/XXjPyCTlQ9FgkY/ybtIw6ns+U7jJs9i2XsbWEav0HqvvHy+JMw3rplBFPE8wYE0TLpI55UE7Ul/jslESkyr/+o0nSuXYsc7F81fCLswNRFzW8aeqP2T1w50HGsmuwKBgHshgdIQHlC3CglOGAv0hjVVHBcNxLCdzPvraC263vnhFXLXYNXJ310mbmN7Sxyk7ISlnvUA8B/yvlOQenM5pUIO86NXbRMTDd4oentWFiKkigki9GSbDMIo8odRfKXgxXP+xHNyPSQBvZCuoVutzE1yl1Lxw1Kw9ikaykhI7+q/AoGAFhobwtBnLU76vxWAxCI6oj7PRcfXSx8u6nOeTCE47IpkY5J0hB6OCpyhkcNAD13FYJ5/269XXEcrlsndIEgiai8/AaiQ51P0uURV4gSMBqq4EnyJYSA/4tneuaJyx91zEOyUzJY2fYPmB/g+jdTdqPWCMyi9IMnKY20tp1doog0CgYBO83gSEdqGmR3+qix2cUBZYXGCNRKFtFX8edIEeluT6AOMA6/kMe5i/y8e3m5Oh9LWE45l04dsVHeqAA6l9Ps/l6WkeLEiIsRY0yF0DcppXo8DJ5TrL+DIJeJ1yxBEGcLjBea5t16zwLqwFASr0ieF622kk40Gn7QH+ZBrMaN1Qw

===========1.公鑰加密,私鑰解密==============
原文:aattaggcctegthththfef/aat.mp4
公鑰加密後的資料:EfjUSb8my/YWrzOziQYKGuB9KbJeZO6uZSRsRZgaEu1m5zHujZ+FA9QK1abjn/ELgCmQw5B91BGFZia2ySbtMLe3n0bD32udI0ufeLA5n/uPEyuiKdrPQcgN22ugJXcrNL9Hbd6WbYbXzeraTK03k61yM2KmgfW/usjbGMjxJ+zoHtw6zHg6lX3O5QrHlx1Q/GUWI61gn4Lp3TsqlRg0YG5/BAOFsRSSdQibK2h2BHxwsiivTidbSc7Z7eSrWPC6T/j0PCgYjsW6O9lRKNdtSlMC6S3Nh9723i0MkqgcE0g8/QV0DxetSbvkFibvaNgh059KLsE0JWyIvINY6bDYFw
私鑰解密後的資料:aattaggcctegthththfef/aat.mp4

===========2.反向進行操作,私鑰加密,公鑰解密==============
原文:4b9d373bed9f40b389f0e42ebaf729b4
私鑰加密後的資料:mQr+BUTDHakOJsUqt+g4UHeUC+pGBM6YjZmMcTFXT3mJw4EcbBdh1UF+R1rWCJc7l2ofsnWMnwosWCPuPJTN8LI2PYNICeXHOLCOWZ2DKz6ARdpZuebpPfnLJ0D5dK1oh/8ndgUiN/SBDaGgIK//3MQp2yRn+O+d3Xv193T2i7vRx/oDyI3/F0Ftbwj3L8RtSPIYv3Zf7c69xTsiYkwGZ3UWCLcEwaLD9d2k60VX2CQntWhJ5mTYHYdjA7z57oMz0hEx7WdUFMM+RLkhOIo8hljY3RjhwDN1BLru6wFfQ5ztnZ6kDaaJRKEdfzjePxZ4MQqI4hgHtHC1NrYV3ZIM0w
公鑰解密後的資料:4b9d373bed9f40b389f0e42ebaf729b4
           

繼續閱讀