Java文件加密与解密实战指南

1. 为什么需要文件加密?

在数据泄露频发的今天,保护敏感文件(如配置文件、用户数据、日志等)至关重要。Java提供了强大的加密库(JCA/JCE),可以轻松实现文件的加密与解密。本文将从基础概念入手,带你实现两种最常见的文件加密方案。

2. 核心概念

  • 对称加密:加密和解密使用同一密钥,速度快,适合大文件。常用算法:AES。
  • 非对称加密:使用公钥加密、私钥解密,安全性高但速度慢,适合小数据。常用算法:RSA。
  • 混合加密:用RSA加密AES的密钥,再用AES加密文件,兼顾安全与性能。

3. 使用AES加密文件(对称加密)

3.1 加密步骤

  1. 生成或加载AES密钥(128/192/256位)。
  2. 创建Cipher对象,初始化为加密模式。
  3. 读取源文件,通过CipherOutputStream写入加密文件。

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.Key;

public class AESFileEncryption {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    private static final byte[] IV = new byte[16]; // 初始化向量,应随机生成

    public static void encrypt(String key, File inputFile, File outputFile) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), ALGORITHM);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        IvParameterSpec ivSpec = new IvParameterSpec(IV);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

        try (FileInputStream inputStream = new FileInputStream(inputFile);
             FileOutputStream outputStream = new FileOutputStream(outputFile);
             CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                cipherOutputStream.write(buffer, 0, bytesRead);
            }
        }
    }
}

4. 使用RSA加密文件(非对称加密,适合小数据)

由于RSA加密速度慢,通常只用于加密对称密钥或小文件(<1KB)。以下示例演示加密密钥的生成与使用。


import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;

public class RSAFileEncryptor {
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        return generator.generateKeyPair();
    }

    public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encryptedData);
    }
}

5. 最佳实践与注意事项

  • 密钥管理:将密钥存储在安全位置(如密钥库、硬件安全模块),切勿硬编码在代码中。
  • IV(初始化向量):对称加密时IV应随机生成并随密文一起存储(通常作为文件前缀)。
  • 大文件处理:使用流式加密避免内存溢出。
  • 性能考虑:对于大文件,推荐AES-GCM模式(提供认证加密)。

6. 总结

Java提供了灵活且强大的加密API。通过本文的示例,你可以快速实现文件加密解密功能。在实际项目中,请务必遵循安全编码规范,定期更新加密算法,并做好密钥的生命周期管理。保护数据,从加密开始。