怎样通过EasyExcel实现数据加密保护隐私

2025-04发布7次浏览

EasyExcel 是阿里巴巴开源的一个基于 Java 的 Excel 处理工具,它极大地简化了对 Excel 文件的读写操作。然而,在实际业务场景中,尤其是涉及敏感数据时,单纯使用 EasyExcel 进行数据处理可能无法满足隐私保护的需求。本文将详细介绍如何通过 EasyExcel 实现数据加密保护隐私。


一、背景与需求分析

在现代企业应用中,用户隐私和数据安全是至关重要的。当通过 Excel 文件传输或存储数据时,敏感信息(如身份证号、手机号码、银行账号等)需要进行加密保护,以防止数据泄露或未经授权的访问。以下是实现数据加密保护的主要需求:

  1. 数据加密:在写入 Excel 文件之前,对敏感字段进行加密。
  2. 数据解密:在从 Excel 文件读取数据时,对加密字段进行解密。
  3. 兼容性:确保加密后的数据格式仍然符合 Excel 的标准,不影响文件的正常读写。

二、技术方案设计

为了实现上述需求,我们可以结合 EasyExcel 和常见的加密算法(如 AES 对称加密)来完成数据的加密与解密。具体步骤如下:

1. 引入依赖

首先,确保项目中引入了 EasyExcel 和加密相关的依赖。以下是一个典型的 Maven 配置示例:

<dependencies>
    <!-- EasyExcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.0.5</version>
    </dependency>
    <!-- 加密支持 -->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.69</version>
    </dependency>
</dependencies>

2. 定义实体类

创建一个包含敏感字段的实体类,并为这些字段提供加密和解密逻辑。

import com.alibaba.excel.annotation.ExcelProperty;

public class UserData {
    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("手机号码")
    private String phone;

    @ExcelProperty("身份证号")
    private String idCard;

    // Getter 和 Setter 方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return CryptoUtil.decrypt(phone); // 解密手机号码
    }

    public void setPhone(String phone) {
        this.phone = CryptoUtil.encrypt(phone); // 加密手机号码
    }

    public String getIdCard() {
        return CryptoUtil.decrypt(idCard); // 解密身份证号
    }

    public void setIdCard(String idCard) {
        this.idCard = CryptoUtil.encrypt(idCard); // 加密身份证号
    }
}

3. 实现加密解密工具类

使用 AES 算法实现加密和解密功能。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class CryptoUtil {
    private static final String ALGORITHM = "AES";
    private static final String KEY = "your-secret-key-123"; // 密钥,长度需为16位

    public static String encrypt(String data) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            byte[] encryptedBytes = cipher.doFinal(data.getBytes());
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            throw new RuntimeException("加密失败", e);
        }
    }

    public static String decrypt(String encryptedData) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            return new String(decryptedBytes);
        } catch (Exception e) {
            throw new RuntimeException("解密失败", e);
        }
    }
}

4. 写入加密数据到 Excel

使用 EasyExcel 将加密后的数据写入 Excel 文件。

import com.alibaba.excel.EasyExcel;

import java.util.ArrayList;
import java.util.List;

public class WriteEncryptedData {
    public static void main(String[] args) {
        String fileName = "encrypted_data.xlsx";

        List<UserData> dataList = new ArrayList<>();
        UserData user1 = new UserData();
        user1.setName("张三");
        user1.setPhone("13800138000"); // 自动加密
        user1.setIdCard("110101199001011234"); // 自动加密
        dataList.add(user1);

        EasyExcel.write(fileName, UserData.class).sheet("Sheet1").doWrite(dataList);
    }
}

5. 从 Excel 读取并解密数据

从 Excel 文件中读取数据时,自动调用解密逻辑。

import com.alibaba.excel.EasyExcel;

import java.util.List;

public class ReadEncryptedData {
    public static void main(String[] args) {
        String fileName = "encrypted_data.xlsx";

        List<UserData> dataList = EasyExcel.read(fileName, UserData.class, null)
                .sheet(0).doReadSync();

        for (UserData userData : dataList) {
            System.out.println("姓名: " + userData.getName());
            System.out.println("手机号码: " + userData.getPhone()); // 自动解密
            System.out.println("身份证号: " + userData.getIdCard()); // 自动解密
        }
    }
}

三、流程图

以下是整个加密与解密流程的 Mermaid 图形化表示:

sequenceDiagram
    participant User as 用户
    participant App as 应用程序
    participant Excel as Excel 文件

    Note over User,App: 用户输入敏感数据
    User->>App: 提供数据(明文)
    App->>App: 调用加密工具类
    App->>Excel: 写入加密后的数据
    Note over Excel,App: 数据存储到 Excel 文件

    Note over Excel,App: 从 Excel 文件读取数据
    Excel->>App: 返回加密数据
    App->>App: 调用解密工具类
    App->>User: 返回解密后的数据

四、扩展讨论

  1. 密钥管理:在实际生产环境中,建议将加密密钥存储在安全的地方(如 KMS 或配置中心),而不是硬编码在代码中。
  2. 性能优化:对于大规模数据加密,可以考虑批量处理或异步任务,以降低系统负载。
  3. 合规性:确保加密算法和密钥长度符合相关法律法规(如 GDPR 或中国《个人信息保护法》)的要求。