Java RSA加密案例如何实操

wen java案例 28

本文目录导读:

Java RSA加密案例如何实操

  1. 基础RSA工具类
  2. 完整使用示例
  3. 处理大文本数据的分段加密
  4. 实用的密钥文件管理
  5. 完整应用示例
  6. Maven依赖
  7. 注意事项

我来详细说明Java RSA加密解密的实操案例。

基础RSA工具类

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil {
    // 生成RSA密钥对
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048); // 推荐2048位
        return generator.generateKeyPair();
    }
    // 公钥加密
    public static String encrypt(String data, String publicKeyStr) throws Exception {
        PublicKey publicKey = getPublicKey(publicKeyStr);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }
    // 私钥解密
    public static String decrypt(String encryptedData, String privateKeyStr) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedBytes, "UTF-8");
    }
    // 获取公钥
    public static PublicKey getPublicKey(String base64PublicKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64PublicKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(spec);
    }
    // 获取私钥
    public static PrivateKey getPrivateKey(String base64PrivateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(spec);
    }
    // 密钥转字符串
    public static String keyToString(Key key) {
        return Base64.getEncoder().encodeToString(key.getEncoded());
    }
}

完整使用示例

public class RSADemo {
    public static void main(String[] args) {
        try {
            // 1. 生成密钥对
            System.out.println("=== 生成密钥对 ===");
            KeyPair keyPair = RSAUtil.generateKeyPair();
            String publicKeyStr = RSAUtil.keyToString(keyPair.getPublic());
            String privateKeyStr = RSAUtil.keyToString(keyPair.getPrivate());
            System.out.println("公钥: " + publicKeyStr);
            System.out.println("私钥: " + privateKeyStr);
            // 2. 加密
            System.out.println("\n=== 加密 ===");
            String originalData = "Hello, RSA加密!";
            String encryptedData = RSAUtil.encrypt(originalData, publicKeyStr);
            System.out.println("原始数据: " + originalData);
            System.out.println("加密结果: " + encryptedData);
            // 3. 解密
            System.out.println("\n=== 解密 ===");
            String decryptedData = RSAUtil.decrypt(encryptedData, privateKeyStr);
            System.out.println("解密结果: " + decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

处理大文本数据的分段加密

import java.util.ArrayList;
import java.util.List;
public class RSALargeDataUtil {
    private static final int MAX_ENCRYPT_BLOCK = 117; // RSA 2048位加密最大块大小
    private static final int MAX_DECRYPT_BLOCK = 128; // RSA 2048位解密最大块大小
    // 分段加密
    public static String encryptLargeData(String data, String publicKeyStr) throws Exception {
        PublicKey publicKey = RSAUtil.getPublicKey(publicKeyStr);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] dataBytes = data.getBytes("UTF-8");
        int inputLength = dataBytes.length;
        List<byte[]> resultList = new ArrayList<>();
        for (int offset = 0; offset < inputLength; offset += MAX_ENCRYPT_BLOCK) {
            int length = Math.min(inputLength - offset, MAX_ENCRYPT_BLOCK);
            byte[] encryptedBlock = cipher.doFinal(dataBytes, offset, length);
            resultList.add(encryptedBlock);
        }
        // 合并所有加密块
        byte[] resultBytes = new byte[resultList.stream().mapToInt(b -> b.length).sum()];
        int destPos = 0;
        for (byte[] block : resultList) {
            System.arraycopy(block, 0, resultBytes, destPos, block.length);
            destPos += block.length;
        }
        return Base64.getEncoder().encodeToString(resultBytes);
    }
    // 分段解密
    public static String decryptLargeData(String encryptedData, String privateKeyStr) throws Exception {
        PrivateKey privateKey = RSAUtil.getPrivateKey(privateKeyStr);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] dataBytes = Base64.getDecoder().decode(encryptedData);
        int inputLength = dataBytes.length;
        List<byte[]> resultList = new ArrayList<>();
        for (int offset = 0; offset < inputLength; offset += MAX_DECRYPT_BLOCK) {
            int length = Math.min(inputLength - offset, MAX_DECRYPT_BLOCK);
            byte[] decryptedBlock = cipher.doFinal(dataBytes, offset, length);
            resultList.add(decryptedBlock);
        }
        // 合并所有解密块
        byte[] resultBytes = new byte[resultList.stream().mapToInt(b -> b.length).sum()];
        int destPos = 0;
        for (byte[] block : resultList) {
            System.arraycopy(block, 0, resultBytes, destPos, block.length);
            destPos += block.length;
        }
        return new String(resultBytes, "UTF-8");
    }
}

实用的密钥文件管理

import java.io.*;
import java.nio.file.*;
public class RSAKeyManager {
    // 保存密钥到文件
    public static void saveKeyToFile(String keyStr, String filePath) throws IOException {
        Files.write(Paths.get(filePath), keyStr.getBytes("UTF-8"));
    }
    // 从文件读取密钥
    public static String loadKeyFromFile(String filePath) throws IOException {
        byte[] bytes = Files.readAllBytes(Paths.get(filePath));
        return new String(bytes, "UTF-8").trim();
    }
    // 保存密钥对
    public static void saveKeyPair(KeyPair keyPair, String publicKeyPath, String privateKeyPath) throws IOException {
        saveKeyToFile(RSAUtil.keyToString(keyPair.getPublic()), publicKeyPath);
        saveKeyToFile(RSAUtil.keyToString(keyPair.getPrivate()), privateKeyPath);
    }
    // 从文件加载密钥对
    public static KeyPair loadKeyPair(String publicKeyPath, String privateKeyPath) throws Exception {
        PublicKey publicKey = RSAUtil.getPublicKey(loadKeyFromFile(publicKeyPath));
        PrivateKey privateKey = RSAUtil.getPrivateKey(loadKeyFromFile(privateKeyPath));
        return new KeyPair(publicKey, privateKey);
    }
}

完整应用示例

public class RSAApplication {
    public static void main(String[] args) {
        try {
            // 1. 生成并保存密钥
            System.out.println("=== 生成并保存密钥 ===");
            KeyPair keyPair = RSAUtil.generateKeyPair();
            RSAKeyManager.saveKeyPair(keyPair, "public_key.pem", "private_key.pem");
            System.out.println("密钥已保存到文件");
            // 2. 从文件加载密钥
            System.out.println("\n=== 从文件加载密钥 ===");
            KeyPair loadedKeyPair = RSAKeyManager.loadKeyPair("public_key.pem", "private_key.pem");
            // 3. 测试加密解密
            String message = "这是一个测试消息,包含特殊字符!@#$%^&*()";
            System.out.println("原始消息: " + message);
            // 加密
            String encrypted = RSAUtil.encrypt(message, 
                RSAUtil.keyToString(loadedKeyPair.getPublic()));
            System.out.println("加密后: " + encrypted);
            // 解密
            String decrypted = RSAUtil.decrypt(encrypted, 
                RSAUtil.keyToString(loadedKeyPair.getPrivate()));
            System.out.println("解密后: " + decrypted);
            // 验证
            System.out.println("\n验证结果: " + message.equals(decrypted));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Maven依赖

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

注意事项

  1. 密钥长度:推荐至少使用2048位
  2. 填充方式:使用PKCS1Padding
  3. 数据长度:RSA加密有长度限制(117字节/2048位密钥)
  4. 性能考虑:RSA不适合加密大量数据,建议配合AES使用
  5. 密钥管理:私钥必须妥善保管,不能泄露
  6. Base64编码:加密结果使用Base64编码便于传输

这个实操案例涵盖了RSA加密解密的完整流程,包括密钥生成、加解密操作、大文本处理以及密钥文件管理等功能。

抱歉,评论功能暂时关闭!