RSA加密算法有一个限制,即一次加密的数据长度不能超过密钥长度减去11字节。在默认情况下,2048位RSA密钥的长度为256字节,因此一次最多只能加密245字节的数据。

如果要加密更长的数据,可以使用分段加密的方式。将数据分成若干块,每块的长度不超过密钥长度减去11字节,然后对每块数据进行加密,最后将所有加密后的数据拼接起来。在解密时,也需要将加密后的数据分成若干块进行解密。

创建RSA加密解密工具类
import javax.crypto.Cipher;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * <p>
 * Description: RSA加密解密工具类
 * </p>
 *
 * @author songzixian
 * @version v2.0.0
 * @create 2023-03-12 12:45
 * @see com.songzixan.rsa.util
 */
public class RsaUtil {

    /**
     * 生成RSA公钥和私钥对
     * @param algorithm 加密算法,例如"RSA"
     * @param keySize 密钥长度,例如2048
     * @return 生成的公钥和私钥对
     * @throws Exception
     */
    public static KeyPair generateKeyPair(String algorithm, int keySize) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        keyPairGenerator.initialize(keySize);
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 将公钥保存到文件中
     * @param publicKey 要保存的公钥
     * @param fileName 保存到的文件名
     * @throws Exception
     */
    public static void savePublicKey(PublicKey publicKey, String fileName) throws Exception {
        byte[] publicKeyBytes = publicKey.getEncoded();
        FileOutputStream fos = new FileOutputStream(fileName);
        fos.write(publicKeyBytes);
        fos.close();
    }
    /**
     * 将私钥保存到文件中
     * @param privateKey 要保存的私钥
     * @param fileName 保存到的文件名
     * @throws Exception
     */
    public static void savePrivateKey(PrivateKey privateKey, String fileName) throws Exception {
        byte[] privateKeyBytes = privateKey.getEncoded();
        FileOutputStream fos = new FileOutputStream(fileName);
        fos.write(privateKeyBytes);
        fos.close();
    }

    /**
     * 从文件中加载公钥
     * @param fileName 公钥文件名
     * @param algorithm 加密算法,例如"RSA"
     * @return 加载出的公钥
     * @throws Exception
     */
    public static PublicKey loadPublicKey(String fileName, String algorithm) throws Exception {
        byte[] publicKeyBytes = Files.readAllBytes(Paths.get(fileName));
        X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        return keyFactory.generatePublic(spec);
    }

    /**
     * 从文件中加载私钥
     * @param fileName 私钥文件名
     * @param algorithm 加密算法,例如"RSA"
     * @return 加载出的私钥
     * @throws Exception
     */
    public static PrivateKey loadPrivateKey(String fileName, String algorithm) throws Exception {
        byte[] privateKeyBytes = Files.readAllBytes(Paths.get(fileName));
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        return keyFactory.generatePrivate(spec);
    }

    /**
     * 加密文件
     * @param algorithm 加密算法,例如"RSA"
     * @param publicKeyFile 公钥文件名
     * @param inputFile 要加密的文件名
     * @param outputFile 加密后的文件名
     * @throws Exception
     */
    public static void encryptFile(String algorithm, String publicKeyFile, String inputFile, String outputFile) throws Exception {
        PublicKey publicKey = loadPublicKey(publicKeyFile, algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        FileInputStream fis = new FileInputStream(inputFile);
        FileOutputStream fos = new FileOutputStream(outputFile);
        byte[] buffer = new byte[245];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            byte[] encrypted = cipher.doFinal(buffer, 0, len);
            fos.write(encrypted);
        }
        fis.close();
        fos.flush();
        fos.close();
    }
    
    /**
     * 解密文件
     * @param algorithm 加密算法,例如"RSA"
     * @param privateKeyFile 私钥文件名
     * @param inputFile 要解密的文件名
     * @param outputFile 解密后的文件名
     * @throws Exception
     */
    public static void decryptFile(String algorithm, String privateKeyFile, String inputFile, String outputFile) throws Exception {
        PrivateKey privateKey = loadPrivateKey(privateKeyFile, algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        FileInputStream fis = new FileInputStream(inputFile);
        FileOutputStream fos = new FileOutputStream(outputFile);
        byte[] buffer = new byte[256];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            byte[] decrypted = cipher.doFinal(buffer, 0, len);
            fos.write(decrypted);
        }
        fis.close();
        fos.flush();
        fos.close();
    }
}
创建RSA测试类
import com.songzixan.rsa.util.RsaUtil;

import java.security.*;

/**
 * <p>
 * Description: RAS文件加密解密测试类
 * </p>
 *
 * @author songzixian
 * @version v2.0.0
 * @create 2023-03-12 12:47
 * @see com.songzixan.rsa.test
 */
public class TestRsa {

    public static void main(String[] args) throws Exception {
        // 秘钥对
        String publicKeyFile = "src/main/resources/public.txt";
        String privateKeyFile = "src/main/resources/private.key";
        // 需要加密的文件
        String inputFile = "src/main/resources/test.txt";
        // 解密后的文件
        String encryptedFile = "src/main/resources/encrypted.dat";
        // 解密后的文件
        String decryptedFile = "src/main/resources/decrypted.txt";
        // 加密算法
        String algorithm = "RSA";
        int keySize = 2048;


        // 生成公钥和私钥 开发中只需要调一次即可
        KeyPair keyPair = RsaUtil.generateKeyPair(algorithm, keySize);
        // 保存公钥
        RsaUtil.savePublicKey(keyPair.getPublic(), publicKeyFile);
        // 保存私钥
        RsaUtil.savePrivateKey(keyPair.getPrivate(), privateKeyFile);

        // 加密文件
        RsaUtil.encryptFile(algorithm, publicKeyFile, inputFile, encryptedFile);

        // 解密文件
        RsaUtil.decryptFile(algorithm, privateKeyFile, encryptedFile, decryptedFile);

    }
}
Last modification:March 12, 2023
如果觉得这篇技术文章对你有用,请随意赞赏