MST

星途 面试题库

面试题:如何通过自定义序列化机制来增强Java序列化的安全性

假设你需要为一个包含敏感信息的Java类实现序列化,要求通过自定义序列化机制来防止可能的安全问题,请描述实现思路并给出关键代码示例。
50.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 实现Serializable接口:让目标类实现java.io.Serializable接口,表明该类的对象可以被序列化。
  2. 定义私有静态变量serialVersionUID:为类定义一个private static final long serialVersionUID,它可以确保不同版本的类在序列化和反序列化时的兼容性。
  3. 使用自定义序列化方法
    • 定义writeObject方法,在其中手动控制敏感信息的序列化过程。例如,可以对敏感信息进行加密后再写入。
    • 定义readObject方法,在其中对读取到的加密敏感信息进行解密,恢复原始数据。

关键代码示例

import java.io.*;

public class SensitiveDataClass implements Serializable {
    private static final long serialVersionUID = 1L;
    private String sensitiveInfo;

    public SensitiveDataClass(String sensitiveInfo) {
        this.sensitiveInfo = sensitiveInfo;
    }

    // 自定义序列化方法
    private void writeObject(ObjectOutputStream out) throws IOException {
        // 假设这里使用简单的字符串替换来模拟加密
        String encryptedInfo = sensitiveInfo.replaceAll(".", "*");
        out.writeObject(encryptedInfo);
    }

    // 自定义反序列化方法
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        String encryptedInfo = (String) in.readObject();
        // 假设这里使用简单的字符串替换来模拟解密
        sensitiveInfo = encryptedInfo.replaceAll("\\*", "a");
    }

    public String getSensitiveInfo() {
        return sensitiveInfo;
    }
}

使用示例

public class Main {
    public static void main(String[] args) {
        SensitiveDataClass data = new SensitiveDataClass("secret information");
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("sensitive.data"))) {
            oos.writeObject(data);
        } catch (IOException e) {
            e.printStackTrace();
        }

        SensitiveDataClass deserializedData = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("sensitive.data"))) {
            deserializedData = (SensitiveDataClass) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        if (deserializedData != null) {
            System.out.println("Deserialized Sensitive Info: " + deserializedData.getSensitiveInfo());
        }
    }
}