`
C_J
  • 浏览: 129641 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

可变hashcode的隐患和序列化安全

阅读更多

可变hashcode的隐患

 

    为识别对象,JDK为每个Object类都定义了一个hashcode,Object的类的hashcode是根据对象的内存地址做hash算法得出来的,String类则自己重写了hashcode()方法,是根据字符串的每个字符做算法累加起来的,Integer在直接返回value的值。

    而很多时候,对于应用系统的一些类(Java Bean),是要根据属性来计算hashcode而非内存地址,就像String类。所以会去覆盖Object的equals方法。其实重写就重写了,但是出于技术上的要求,JDK的一些数据结构Collection作为一个数据的容器,它需要唯一定位某个对象,而判定对象是否相等的标准是:1,hashcode是否相等;2,equals函数是否返回true。所以如果这些Java Bean用到这些Collection的话重写equals就必须同时重写hashcode了。

    但这不是重点,重点是另外一个问题:可变的hashcode带来的BUG。

 

大师Ted给出了例子,如下:

import java.util.*;

public class Person
    implements Iterable<Person>
{
    public Person(String fn, String ln, int a, Person... kids)
    {
        this.firstName = fn; this.lastName = ln; this.age = a;
        for (Person kid : kids)
            children.add(kid);
    }
    
    // ...
    
    public void setFirstName(String value) { this.firstName = value; }
    public void setLastName(String value) { this.lastName = value; }
    public void setAge(int value) { this.age = value; }
    
    public int hashCode() {
        return firstName.hashCode() & lastName.hashCode() & age;
    }

    // ...

    private String firstName;
    private String lastName;
    private int age;
    private List<Person> children = new ArrayList<Person>();
}


// MissingHash.java
import java.util.*;

public class MissingHash
{
    public static void main(String[] args)
    {
        Person p1 = new Person("Ted", "Neward", 39);
        Person p2 = new Person("Charlotte", "Neward", 38);
        System.out.println(p1.hashCode());
        
        Map<Person, Person> map = new HashMap<Person, Person>();
        map.put(p1, p2);
        
        p1.setLastName("Finkelstein");
        System.out.println(p1.hashCode());
        
        System.out.println(map.get(p1));
    }
}

 

    可以看到这个Person重写了hashcode,是属性的hashcode做与运算得出的结果。但是注意到,当p1对象作为key放入HashMap后,随后改变了lastName的属性,导致p1对象的hashcode发生了改变,从而System.out.println(map.get(p1));直接输出null。

    所以可以看到,在重写hashcode的时候要特别注意可变的hashcode的影响,为了消除这种隐患,最好给属性加上final的限制。

 

 

序列化安全问题

    java中序列化对象可以用户磁盘存储和网络传输对象等,但如果不经过任何处理则这些流都是明文的,具有安全隐患,我们通过模糊化处理或使用SealedObject加密等方法来保证安全,如下:

 

1,模糊化处理,如下:

    JAVA对于序列化、反序列化的类是利用ObjectOutputStream、ObjectIntputStream实现,如果需要序列化的类没有writeObject和readObject的方法话,则会调用默认的序列化方式,所以只要重写这两个方法就可以实现自定义的方式来增加安全性等特殊处理(JDK应该是考虑到了安全等问题才给与扩展),如下:

package com.tedneward;

public class Person
    implements java.io.Serializable
{
    public Person(String fn, String ln, int a)
    {
        this.firstName = fn; this.lastName = ln; this.age = a;
    }
    
    public String getFirstName() { return firstName; }
    public String getLastName() { return lastName; }
    public int getAge() { return age; }
    public Person getSpouse() { return spouse; }
    
    public void setFirstName(String value) { firstName = value; }
    public void setLastName(String value) { lastName = value; }
    public void setAge(int value) { age = value; }
    public void setSpouse(Person value) { spouse = value; }
    
    private void writeObject(java.io.ObjectOutputStream stream)
        throws java.io.IOException
    {
        // "Encrypt"/obscure the sensitive data
        age = age << 2;
        stream.defaultWriteObject();
    }
    
    private void readObject(java.io.ObjectInputStream stream)
        throws java.io.IOException, ClassNotFoundException
    {
        stream.defaultReadObject();

        // "Decrypt"/de-obscure the sensitive data
        age = age >> 2;
    }
    
    
    private String firstName;
    private String lastName;
    private int age;
    private Person spouse;
}

 

 

 

 

2,使用SealedObject对对象进行加密,然后序列化,如下:

 

 

import java.io.Serializable;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SealedObject;
import javax.crypto.SecretKey;

public class MainClass {
  public static void main(String args[]) throws Exception {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    SecretKey secretKey;
    Cipher encrypter, decrypter;

    secretKey = KeyGenerator.getInstance("DES").generateKey();// des加密

    encrypter = Cipher.getInstance("DES");
    encrypter.init(Cipher.ENCRYPT_MODE, secretKey);

    decrypter = Cipher.getInstance("DES");
    decrypter.init(Cipher.DECRYPT_MODE, secretKey);

    MyClass cust, unsealed;
    SealedObject sealed;

    cust = new MyClass();
    cust.name = "Paul";
    cust.password = "password";

    // Seal it, storing it in a SealedObject
    sealed = (new SealedObject(cust, encrypter));
    
    FileOutputStream fos = new FileOutputStream(args[0]);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(sealed);
    oos.close();

    // Try unsealing it
    String algorithmName = sealed.getAlgorithm();
    System.out.println(algorithmName);
    unsealed = (MyClass) sealed.getObject(decrypter);

    System.out.println("NAME: " + unsealed.name);
    System.out.println("PASSWORD: " + unsealed.password);

  }
}

class MyClass implements Serializable {
  public String name;

  public String password;
}

 

 

分享到:
评论

相关推荐

    最全java八股文高级/资深面试题

    枚举单例是Java中最安全且防止反序列化重新创建单例的方法。 3. **NIO、BIO、AIO**:Java的非阻塞I/O(NIO)提供了异步I/O能力,比传统的阻塞I/O(BIO)更高效,因为它允许一个线程处理多个通道。AIO(Async I/O)...

    (源码)基于Java的论坛管理系统.zip

    # 基于Java的论坛管理系统 ## 项目简介 本项目是一个基于Java的论坛管理系统,旨在提供一个功能齐全的论坛平台,支持用户注册、登录、发帖、回帖、管理板块、管理用户等功能。系统分为普通用户、版主和管理员三种角色,每种角色拥有不同的权限和操作功能。 ## 项目的主要特性和功能 ### 用户管理 注册与登录用户可以注册新账号并使用账号登录系统。 用户权限管理系统支持普通用户、版主和管理员三种角色,每种角色拥有不同的权限。 黑名单管理用户可以将其他用户加入黑名单,屏蔽其内容。 用户状态管理管理员可以禁用或启用用户账号。 ### 板块管理 板块创建与删除管理员可以创建新的论坛板块,并删除不再需要的板块。 板块管理员设置管理员可以为每个板块设置管理员,管理员可以对板块内容进行管理。 ### 帖子管理 发帖与回帖用户可以在指定板块发布新帖子和回复帖子。 帖子置顶与取消置顶版主可以将帖子置顶,突出显示重要内容。

    (源码)基于Vue.js的通用组件库.zip

    # 基于Vue.js的通用组件库 ## 项目简介 此项目是基于Vue.js构建的组件库,涵盖了Button、Form、FormItem、Input、Notice等多个可复用组件。它具备组件测试、文档生成、自定义主题、按需加载、组件数据通信等功能,并且通过Webpack完成打包,方便在各类Vue项目中使用。 ## 项目的主要特性和功能 1. 多种加载方式支持全局引入和按需加载,可根据项目需求灵活选择。 2. 文档生成利用VuePress工具生成组件文档,便于用户查看组件使用方法和样式。 3. 自定义主题能通过修改样式变量来自定义组件主题,满足不同项目的个性化需求。 4. 组件数据通信通过dispatch和broadcast方法实现组件间的数据通信,提升组件库的扩展性。 5. 独立打包样式文件和组件文件分别打包,可单独加载,减少代码量和加载时间。 ## 安装使用步骤 ### 准备工作 确保已经安装基本的Node.js和npm环境,以及Git。

    JAVA+access综合测评系统毕业设计(源代码+论文+开题报告+任务书).zip

    Java项目课程设计,包含源码+数据库+论文

    数据库系统原理练习试题库.doc

    数据库系统原理练习试题库.doc

    trash-cli-0.21.4.18-2.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统trash-cli-0.21.4.18-2.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf trash-cli-0.21.4.18-2.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    Delphi 12.3 控件之QRCodeScaner.apk.rar

    Delphi 12.3 控件之QRCodeScaner.apk.rar

    基于JAVA的安全电子商务(论文).zip

    Java项目课程设计,包含源码+数据库+论文

    (源码)基于Python的机器学习实战项目.zip

    # 基于Python的机器学习实战项目 ## 项目简介 这是一个基于Python的机器学习实战项目,涵盖了多种机器学习算法的实现,包括KNN、决策树、朴素贝叶斯、逻辑回归、SVM、集成学习(如AdaBoost)以及线性回归和局部加权线性回归等。每个算法都有对应的Python代码实现,并提供了数据加载、模型训练和预测等基本功能。项目目标是让学习者通过实际代码练习,深入理解并掌握各种机器学习算法的原理和应用。 ## 项目的主要特性和功能 1. KNN(K最近邻)实现KNN分类算法,可用于分类任务,如文本分类、图像识别等。 2. 决策树实现基于ID3算法的决策树分类器,可用于处理分类问题。 3. 朴素贝叶斯实现朴素贝叶斯分类器,用于文本分类任务。 4. 逻辑回归实现逻辑回归模型,用于二分类问题。 5. SVM(支持向量机)实现SVM分类器,可用于多分类问题。 6. 集成学习实现AdaBoost算法,通过组合多个弱学习器创建一个强学习器。

    德国SCA自动涂胶机系统的技术剖析与应用:多轴协同控制、PID调节及通信协议详解

    内容概要:本文深入探讨了德国SCA自动涂胶机系统的关键技术和应用场景。首先介绍了涂胶机系统的工作原理和技术资料的重要组成部分,如设备的工作原理、部件性能参数以及操作使用方法。文中提供了多个代码示例,包括涂胶速度控制、PID算法实现、通信协议(改良版Modbus TCP)、运动轨迹规划(贝塞尔曲线平滑处理)等,展示了系统内部复杂而精细的控制逻辑。此外,还分享了一些实用的经验和技巧,如胶量闭环控制、姿态数据传输、加速度突变检测算法等,帮助用户更好地理解和维护设备。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对涂胶机系统感兴趣的从业者。 使用场景及目标:适用于希望深入了解SCA自动涂胶机系统工作原理、进行设备维护、升级或二次开发的专业人士。通过学习本文,可以掌握涂胶机系统的多轴协同控制、PID调节、通信协议等方面的知识,提高设备的稳定性和效率。 其他说明:文中不仅包含了理论性的解释,还有大量的实战经验和代码示例,有助于读者将所学应用于实际工作中。

    (源码)基于JavaScript的LeetCode算法题解集合.zip

    # 基于JavaScript的LeetCode算法题解集合 ## 项目简介 本项目是一个基于JavaScript的LeetCode算法题解集合,涵盖了从简单到困难的多种算法问题。每个问题的解决方案都经过精心编写和优化,旨在帮助开发者更好地理解和掌握算法与数据结构。项目中的代码可以直接用于LeetCode平台上的题目提交,并且每个文件都包含了详细的解题思路和关键点。 ## 项目的主要特性和功能 1. 广泛的题目覆盖涵盖了LeetCode上的多种题目类型,包括数组、字符串、链表、树、动态规划、回溯、贪心算法等。 2. 详细的解题思路每个问题的解决方案都附带了详细的解题思路和关键点,帮助开发者理解算法的核心思想。 3. 多种解法部分问题提供了多种解法,帮助开发者从不同角度理解问题。 4. 代码简洁高效所有代码都经过优化,确保在时间和空间复杂度上达到最优。 ## 安装使用步骤 1. 下载项目源码将本项目的源码下载到本地。

    Delphi 12.3控件之ODE 多功能助手 Setup 1.0.9.rar

    Delphi 12.3控件之ODE 多功能助手 Setup 1.0.9.rar

    Delphi 12.3控件之MiTeC System Information Component Suite v15.2.1 for Delphi 6-12 Athens Full Source.ra

    Delphi 12.3控件之MiTeC System Information Component Suite v15.2.1 for Delphi 6-12 Athens Full Source.ra

    中药师别网站,有前端、后端、数据集等完整的资源

    中药师别网站,有前端、后端、数据集等完整的资源

    (源码)基于Go和Beego框架的项目部署平台.zip

    # 基于Go和Beego框架的项目部署平台 ## 项目简介 本项目是基于Go语言和Beego框架构建的项目部署平台。它能实现服务升级重启、远程shell执行等操作,支持Java、Nodejs、Shell、JS以及各类中间件的升级发布,可简化项目部署流程,提升部署效率。 ## 项目的主要特性和功能 1. 支持服务在不影响现有运行状态下进行升级和重启。 2. 允许用户在服务器上执行Shell命令,用于项目部署或环境配置。 3. 能对Java、Nodejs、Shell、JS以及各类中间件进行升级发布。 4. 提供简单界面,便于用户进行项目的发布、配置和管理。 5. 具备身份验证和权限管理,保障只有授权用户可执行项目部署操作。 ## 安装使用步骤 假设用户已下载本项目的源码文件 1. 确保已安装Go语言开发环境并配置好环境变量。 2. 在项目目录下运行go get命令安装项目所需依赖库。 3. 根据项目配置文件,配置数据库连接信息。

    (源码)基于软件开发的实时与嵌入式系统课程项目(简称“SISRE”).zip

    # 基于软件开发的实时与嵌入式系统课程项目(简称“SISRE”) ## 项目简介 本项目是为软件开发的实时与嵌入式系统课程(简称“SISRE”)设立的存储库,它专注于研究和实现实时系统中的重要技术和应用。这是一个关于实践项目中各种文件和模块的集合,旨在帮助学生和开发者理解实时系统的设计和实现过程。 ## 项目的主要特性和功能 ### 主要特性 模块化设计项目包含多个模块,每个模块独立实现特定的功能,便于管理和扩展。 实时性能优化注重实时响应和性能优化,确保系统在各种条件下都能快速响应。 嵌入式系统支持项目中的代码适用于多种嵌入式系统平台,具备良好的跨平台兼容性。 ### 功能概览 任务调度与管理实现实时任务调度,确保任务按照优先级和时间约束执行。 实时数据处理处理和分析实时数据,包括传感器数据、实时信号等。 系统监控与调试提供系统性能监控功能,支持在开发过程中的调试功能。 中断管理高效处理系统中断,确保关键任务的及时处理。

    from rtl to gds电子课件,仅用于学习

    from rtl to gds电子课件,仅用于学习

    Delphi 12.3控件之MiTeC-System-Information-Component-Suite-15.1.0-Full-Source.rar

    Delphi 12.3控件之MiTeC_System_Information_Component_Suite_15.1.0_Full_Source.rar

    LabVIEW与Halcon联合编程:图像处理与自动化控制的高效集成

    内容概要:本文详细介绍了LabVIEW与Halcon联合编程的具体实现方法及其应用场景。主要内容涵盖三个关键步骤:LabVIEW采集图像、将图像传递给Halcon处理以及LabVIEW读取并展示Halcon的处理结果。文中还深入讨论了图像数据传递的最佳实践,如直接内存传递而非保存再读取的方式,提高了效率。此外,文章提供了使用.NET构造器调用Halcon算子和HDevEngine调用Halcon脚本的方法,并分享了多个实用技巧,如内存管理、版本兼容性和性能优化等。 适合人群:从事图像处理、自动化控制领域的工程师和技术人员,尤其是对LabVIEW和Halcon有一定了解的开发者。 使用场景及目标:适用于需要高效图像处理和自动化控制的工业检测项目,旨在提高图像处理的速度和准确性,减少开发时间和成本。 其他说明:文中提到的技术细节和代码示例均基于LabVIEW 2018 (32-bit) 和 Halcon 17,对于更高版本或其他环境可能需要调整。同时,作者强调了版本兼容性和内存管理的重要性,提醒读者在实际应用中要注意这些问题。

    Delphi 12.3 控件之nrCommLib Pro v9.69 D7-XE7-XE10.4-XE11-XE12.1 Cracked.rar

    Delphi 12.3 控件之nrCommLib Pro v9.69 D7-XE7-XE10.4-XE11-XE12.1 Cracked.rar

Global site tag (gtag.js) - Google Analytics