使用RSA非对称加密加密明文

RSA非对称加密:原理、应用与实践

https://cloud.baidu.com/article/3155891

项目中使用到的常量


    private static final Log log = LogFactory.get();

    // 定义RSA密钥的长度为2048位
    private static final int RSA_KEY_SIZE = 2048;

    // 指定RSA算法的名称
    private static final String RSA_ALGORITHM = "RSA";

生成RSA密钥对,并分别保存公钥和私钥

    public static void createKey(String publicKeyPath, String privateKeyPath, String charset) {
        // 检查输入参数是否合法,如果存在null或空字符串,则抛出异常
        if (publicKeyPath == null || publicKeyPath.isEmpty() ||
                privateKeyPath == null || privateKeyPath.isEmpty() ||
                charset == null || charset.isEmpty()) {
            throw new IllegalArgumentException("Parameters cannot be null or empty.");
        }

        // 根据输入的字符集名称获取Charset对象
        Charset cs;
        try {
            cs = Charset.forName(charset);
        } catch (IllegalArgumentException e) {
            // 如果字符集无效,抛出异常
            throw new IllegalArgumentException("Invalid charset: " + charset, e);
        }

        try {
            // 实例化密钥生成器
            KeyPairGenerator rsa = KeyPairGenerator.getInstance(RSA_ALGORITHM);
            // 初始化密钥生成器为2048位
            rsa.initialize(RSA_KEY_SIZE);
            // 生成密钥对
            KeyPair keyPair = rsa.generateKeyPair();

            // 将公钥编码为Base64格式字符串并写入文件
            FileUtils.writeFileContent(publicKeyPath, new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()), cs), charset);
            // 将私钥编码为Base64格式字符串并写入文件
            FileUtils.writeFileContent(privateKeyPath, new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()), cs), charset);

        } catch (NoSuchAlgorithmException e) {
            // 如果RSA算法不可用,记录错误日志
            log.error("Failed to generate RSA key pair: Algorithm not available.", e);
            throw new RuntimeException("Failed to generate RSA key pair: Algorithm not available.", e);
        }
    }

根据公钥文件路径获取PublicKey对象

public static PublicKey getPublicKey(String publicKeyPath, String charset) {
        try {
            // 读取公钥文件内容
            String publicKeyStr = FileUtils.getFileContent(publicKeyPath, charset);
            // 对读取的公钥内容进行Base64解码
            byte[] decodedKey = Base64.getDecoder().decode(publicKeyStr);
            // 获取RSA算法的KeyFactory实例
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            // 根据解码后的公钥字节数组生成PublicKey对象
            return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            // RSA算法相关异常处理
            log.error("Failed to generate public key from the specified key specification.", e);
            throw new RuntimeException(e);
        }
    }

根据私钥路径获取私钥对象

    public static PrivateKey getPrivateKey(String privateKeyPath, String charset) {
        try {
            // 读取私钥文件内容
            String privateKey = FileUtils.getFileContent(privateKeyPath, charset);
            // 对读取的内容进行Base64解码
            byte[] decode = Base64.getDecoder().decode(privateKey);
            // 创建RSA密钥工厂
            KeyFactory rsa = KeyFactory.getInstance(RSA_ALGORITHM);
            // 使用解码后的密钥材料生成私钥对象
            return rsa.generatePrivate(new PKCS8EncodedKeySpec(decode));
        } catch (Exception e) {
            // RSA算法相关异常处理
            log.error("Failed to generate private key from the specified key specification.", e);
            throw new RuntimeException(e);
        }
    }

使用RSA公钥加密明文

    public static String encrypt(String plainText, PublicKey publicKey, String charset) {
        try {
            // 使用RSA算法的Cipher对象进行加密操作
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            // 初始化Cipher对象为加密模式
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 对明文进行加密
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(Charset.forName(charset)));
            // 将加密后的字节数组转换为Base64编码的字符串
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            log.error("Encryption failed {}", e.getMessage(), e);
            throw new RuntimeException("Failed to encrypt the plaintext", e);
        }
    }

使用RSA算法和私钥对已加密的文本进行解密

    public static String decrypt(String encryptedText, PrivateKey privateKey, String charset) {
        try {
            // 创建Cipher实例,指定使用RSA算法
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            // 初始化Cipher为解密模式,并使用提供的私钥
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 使用Base64解码器将已加密的文本解码为字节数组
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
            // 使用Cipher解密字节数组
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            // 使用指定的字符集解码解密后的字节数组,并返回字符串
            return new String(decryptedBytes, Charset.forName(charset));
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            log.error("Error during decryption: " + e.getMessage(), e);
            throw new RuntimeException("Error during decryption", e);
        }
    }

使用到的工具类 FileUtils

将字符串内容写入指定文件
	public static void writeFileContent(String filePath, String content, String charset) {
        // 根据文件路径创建File对象
        File file = new File(filePath);

        // 检查文件是否存在,如果不存在则尝试创建
        if (!file.exists()) {
            boolean created = false;
            try {
                created = file.createNewFile();
            } catch (IOException e) {
                log.error("Failed to create the file: " + filePath, e);
                throw new RuntimeException("Failed to create the file: " + filePath);
            }
            if (!created) {
                throw new RuntimeException("Failed to create the file: " + filePath);
            }
        }

        // 使用指定字符集创建OutputStreamWriter,用于写入文件内容
        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), charset != null ? Charset.forName(charset) : StandardCharsets.UTF_8)) {
            // 写入字符串内容到文件
            writer.write(content);
        } catch (IOException e) {
            // 如果发生IO异常,记录错误信息并抛出运行时异常
            log.error("Failed to write to file: {} ", filePath, e);
            throw new RuntimeException("Failed to write to file: " + filePath, e);
        }
    }

读取文件内容
	public static String getFileContent(String filePath, String charset) {
        // 检查文件路径是否为空或null
        if (filePath == null || filePath.isEmpty()) {
            throw new IllegalArgumentException("File path cannot be null or empty.");
        }

        // 检查编码格式是否为空或null
        if (charset == null || charset.isEmpty()) {
            throw new IllegalArgumentException("Charset cannot be null or empty.");
        }

        try {
            // 使用StringJoiner拼接文件内容,行之间使用系统特定的行分隔符分隔
            StringJoiner joiner = new StringJoiner(System.lineSeparator());

            // 使用Files工具类读取文件内容
            Path path = Paths.get(filePath);
            try (Stream<String> lines = Files.lines(path, Charset.forName(charset))) {
                lines.forEach(joiner::add);
            }

            // 返回读取到的文件内容
            return joiner.toString();
        } catch (IOException e) {
            // 如果发生IO异常,记录错误信息并抛出运行时异常
            log.error("Failed to read file: {} ", filePath, e);
            throw new RuntimeException("Failed to read file: " + filePath, e);
        }
    }

加密使用到的依赖

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

 		<!-- 引入Apache Log4j核心库,用于日志管理 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.23.1</version>
        </dependency>
        <!-- 引入Hutool日志工具库,简化日志操作 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-log</artifactId>
            <version>5.8.28</version>
        </dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值