RSA非對稱加密解密工具類

package com.zjmzxfzhl.common.core.util;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
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;

;

/**
 * 公鑰和私鑰是成對的,公鑰加密要用私鑰解密,私鑰加密要用公鑰解密。每次加密結(jié)果是變化的。
 * 1、公鑰加密,私鑰解密用于信息加密。
 * 2、私鑰加密,公鑰解密。
 * 3、私鑰簽名,公鑰驗證。在https中公鑰任何人都有,用私鑰加密意義不大,還不如使用簽名。
 * 簽名實際上是對明文的摘要做了加密。收到的人會收到明文和簽名,利用公鑰可以進(jìn)行驗證真?zhèn)?,?shù)字簽名保證信息是服務(wù)端發(fā)的,并且沒有遭到篡改。
 * 前面兩點(diǎn)是加密,后面一點(diǎn)是認(rèn)證。兩者的側(cè)重點(diǎn)是不同的。后面一點(diǎn)鑒別服務(wù)端的真?zhèn)? * @2023年9月12日
 * https://blog.csdn.net/u014644574/article/details/128810787
 */
public class RSAUtil {
    //定義加密方式
    public static final String KEY_RSA = "RSA";
    //定義簽名算法
    private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
    //公鑰
    public final static String publicKey = "..........";
    //私鑰
    public final static String privateKey = ".................";


    public static void main(String[] args) {
        //生成新的公私密鑰對
//        init();

        String str = "你好, RSA!";
        // 公鑰加密,私鑰解密
        String enStr1 = RSAUtil.encryptByPublic(str, publicKey);
        System.out.println("公鑰加密后:" + enStr1);
        String deStr1 = RSAUtil.decryptByPrivate(enStr1, privateKey);
        System.out.println("私鑰解密后:" + deStr1);

//        // 私鑰加密,公鑰解密
//        String enStr2 = RSAUtil.encryptByPrivate(str, privateKey);
//        System.out.println("私鑰加密后:" + enStr2);
//        String deStr2 = RSAUtil.decryptByPublic(enStr2, publicKey);
//        System.out.println("公鑰解密后:" + deStr2);

//        // 產(chǎn)生簽名
//        String sign = sign(enStr2, privateKey);
//        System.out.println("簽名:" + sign);
//        // 驗證簽名
//        boolean status = verify(enStr2, publicKey, sign);
//        System.out.println("驗證簽名狀態(tài):" + status);

    }

    /**
     * 生成公私密鑰對
     * @date:2018年10月31日 上午11:16:41
     */
    public static void init() {
        try {
            KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
            //設(shè)置密鑰對的bit數(shù),越大越安全,但速度減慢,一般使用512或1024
            generator.initialize(1024);
            KeyPair keyPair = generator.generateKeyPair();
            // 獲取公鑰  
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 獲取私鑰  
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // Base64編碼的公鑰字符串
            String publicKeyStr = encryptBase64(publicKey.getEncoded());
            //Base64編碼的私鑰字符串
            String privateKeyStr = encryptBase64(privateKey.getEncoded());
            // 打印密鑰對
            System.out.println("publicKey=" + publicKeyStr);
            System.out.println("privateKey=" + privateKeyStr);
        } catch (NoSuchAlgorithmException e) {
           e.printStackTrace();
        }
    }

    /**
     * BASE64 解碼
     * @param key 需要Base64解碼的字符串
     * @date:2018年10月31日 上午11:17:46
     */
    public static byte[] decryptBase64(String key) {
        return Base64.getDecoder().decode(key);
    }

    /**
     * BASE64 編碼
     * @param key 需要Base64編碼的字節(jié)數(shù)組
     * @date:2018年10月31日 上午11:18:03
     */
    public static String encryptBase64(byte[] key) {
        return new String(Base64.getEncoder().encode(key));
    }

    /**
     * 公鑰加密
     * @param encryptingStr 字符串
     * @param publicKeyStr  公鑰
     * @date:2018年10月31日 上午11:18:17
     */
    public static String encryptByPublic(String encryptingStr, String publicKeyStr) {
        try {
            // 將公鑰由字符串轉(zhuǎn)為UTF-8格式的字節(jié)數(shù)組
            byte[] publicKeyBytes = decryptBase64(publicKeyStr);
            // 獲得公鑰  
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            // 取得待加密數(shù)據(jù)
            byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            PublicKey publicKey = factory.generatePublic(keySpec);
            // 對數(shù)據(jù)加密  
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 返回加密后由Base64編碼的加密信息
            return encryptBase64(cipher.doFinal(data));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 私鑰解密
     * @param encryptedStr  字符串
     * @param privateKeyStr 私鑰
     * @date:2018年10月31日 上午11:18:36
     */
    public static String decryptByPrivate(String encryptedStr, String privateKeyStr) {
        try {
            // 對私鑰解密  
            byte[] privateKeyBytes = decryptBase64(privateKeyStr);
            // 獲得私鑰 
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            // 獲得待解密數(shù)據(jù)
            byte[] data = decryptBase64(encryptedStr);
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            PrivateKey privateKey = factory.generatePrivate(keySpec);
            // 對數(shù)據(jù)解密
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 返回UTF-8編碼的解密信息
            return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 私鑰加密
     * @param encryptingStr 字符串
     * @param privateKeyStr 私鑰
     * @date:2018年10月31日 上午11:18:57
     */
    public static String encryptByPrivate(String encryptingStr, String privateKeyStr) {
        try {
            byte[] privateKeyBytes = decryptBase64(privateKeyStr);
            // 獲得私鑰  
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            // 取得待加密數(shù)據(jù)
            byte[] data = encryptingStr.getBytes(StandardCharsets.UTF_8);
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            PrivateKey privateKey = factory.generatePrivate(keySpec);
            // 對數(shù)據(jù)加密 
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            // 返回加密后由Base64編碼的加密信息
            return encryptBase64(cipher.doFinal(data));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公鑰解密
     * @param encryptedStr 字符串
     * @param publicKeyStr 公鑰
     * @date:2018年10月31日 上午11:19:07
     */
    public static String decryptByPublic(String encryptedStr, String publicKeyStr) {
        try {
            // 對公鑰解密  
            byte[] publicKeyBytes = decryptBase64(publicKeyStr);
            // 取得公鑰  
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
            // 取得待加密數(shù)據(jù)
            byte[] data = decryptBase64(encryptedStr);
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            PublicKey publicKey = factory.generatePublic(keySpec);
            // 對數(shù)據(jù)解密  
            Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            // 返回UTF-8編碼的解密信息
            return new String(cipher.doFinal(data), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 用私鑰對私鑰加密數(shù)據(jù)進(jìn)行簽名
     * @param encryptedStr 私鑰加密后的字符串
     * @param privateKey   私鑰
     * @date:2018年10月31日 上午11:19:37
     */
    public static String sign(String encryptedStr, String privateKey) {
        String str = "";
        try {
            //將私鑰加密數(shù)據(jù)字符串轉(zhuǎn)換為字節(jié)數(shù)組
            byte[] data = encryptedStr.getBytes(StandardCharsets.UTF_8);
            // 解密由base64編碼的私鑰  
            byte[] bytes = decryptBase64(privateKey);
            // 構(gòu)造PKCS8EncodedKeySpec對象  
            PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
            // 指定的加密算法  
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            // 取私鑰對象  
            PrivateKey key = factory.generatePrivate(pkcs);
            // 用私鑰對信息生成數(shù)字簽名  
            Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
            signature.initSign(key);
            signature.update(data);
            str = encryptBase64(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 校驗數(shù)字簽名
     * @param encryptedStr 私鑰加密后的字符串
     * @param publicKey    公鑰
     * @param sign         簽名
     * @date:2018年10月31日 上午11:19:50
     */
    public static boolean verify(String encryptedStr, String publicKey, String sign) {
        try {
            //將私鑰加密數(shù)據(jù)字符串轉(zhuǎn)換為字節(jié)數(shù)組
            byte[] data = encryptedStr.getBytes(StandardCharsets.UTF_8);
            // 解密由base64編碼的公鑰  
            byte[] bytes = decryptBase64(publicKey);
            // 構(gòu)造X509EncodedKeySpec對象  
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
            // 指定的加密算法  
            KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
            // 取公鑰對象  
            PublicKey key = factory.generatePublic(keySpec);
            // 用公鑰驗證數(shù)字簽名  
            Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
            signature.initVerify(key);
            signature.update(data);
            return signature.verify(decryptBase64(sign));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容