[Java安全入门]二.序列化与反序列化
一.概念
Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反序列化
二.要求
只有实现了Serializable或Externalizable接口的类的对象才能被序列化,并且序列化对象的所有属性都需是可序列化的。
三.实现
serializable接口
1.1方法
序列化:创建一个ObjectOutputStream输出流,调用 ObjectOutputStream 对象的 writeObject() 输出可序列化对象
反序列化:创建一个ObjectInputStream输出流,调用 ObjectInputStream 对象的 readObject()得到反序列化的对象
1.2代码
import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}
User{name=tao, age=20}
1.3注意
①如果实现 Serializable 接口的类有父类,则父类也必须可以序列化,若父类没有实现序列化接口,则父类必须有无参构造函数,否则会抛异常 java.io.InvalidClassException。因为在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果没有在父类无参构造函数中对父类变量进行初始化的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。
②序列化不保存静态变量,因为序列化保存的是对象的状态而不是类的状态,静态变量是类的状态
③ 使用transient 关键字可以选择不需要序列化的字段
如:
private transient String name;
private transient int age;
进行序列化的时候,name和age都不会被保存
Externalizable接口
2.1注意
①Externalizable接口继承Serializable 接口
②writeExternal()和readExternal()对应writeObject()和readObject()两个方法
③Externalizable序列化没有属性限制,静态变量以及transient 关键字修饰的属性都能被序列化
④必须提供public的无参构造方法,因为在反序列化实现 Externalizabale 接口的类的时需要通过反射创建对象。如果没有无参数的构造方法,在运行时会抛出异常:java.io.InvalidClassException
2.2代码
import java.io.*;
import java.lang.reflect.Method;class User implements Externalizable{private String name;private int age;public User(){}//加上public无参构造器@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Override//重写writeExternal()方法public void writeExternal(ObjectOutput out) throws IOException{out.writeObject(name);}@Override//重写wreadExternal()方法public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{name=(String)in.readObject();}}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}
result
User{name=tao, age=0}
age变成了0
因为使用Externalizable接口,需要重写writeExternal() 与 readExternal() 方法,我只写了name的实现,没有写age,int型默认值为0
四.安全
java反序列化会自动触发readObject()方法,类似于php反序列化的__destruct()函数
java支持自定义writeObject()和readObject()方法
如果某个类中自定义了readObject()方法,当对其的一个实例化对象进行反序列化,就会调用readObject()方法
import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private void readObject(ObjectInputStream in){System.out.println("这是新的readObject!");}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}
结果
这是新的readObject!
User{name=null, age=0}
可见在反序列化的时候实现了新的readObject()
那么就可以命令执行了
private void readObject(ObjectInputStream in) throws IOException{Runtime.getRuntime().exec("calc");}
弹计算器了!
这里初步了解java序列化与反序列话,后续构造链会继续学习。
参考博客
java基础知识点2:序列化与反序列化详解_java序列化和反序列化-CSDN博客
javasec/2.java序列化与反序列化.md at master · Maskhe/javasec (github.com)
相关文章:

[Java安全入门]二.序列化与反序列化
一.概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反…...

Dutree:Linux 文件系统磁盘使用追踪工具
在 Linux 系统中,对文件系统的磁盘使用情况进行跟踪和管理是至关重要的。dutree 是一个功能强大的工具,它能够以可视化的方式展示文件系统中的目录和文件的大小,帮助用户更好地了解磁盘空间的使用情况。本文将介绍 dutree 工具的使用方法、功…...

http和https的区别是什么?
–前言 传输信息安全性不同、连接方式不同、端口不同、证书申请方式不同 一、传输信息安全性不同 1、http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。 2、h…...

学习Android的第十九天
目录 Android ExpandableListView 分组列表 ExpandableListView 属性 ExpandableListView 事件 ExpandableListView 的 Adapter 范例 参考文档 Android ViewFlipper 翻转视图 ViewFlipper 属性 ViewFlipper 方法 为 ViewFlipper 加入 View 例子:全屏幕可…...

C#上位机调试经验
1.使用Visual Studio的远程工具 因为上位机软件安装在工控机上,不方便调试。如果直接把代码放在工控机上,又不太安全。 可以在工控机上安装一个Visual Studio的远程工具,把随身带的笔记本电脑通过网线插在工控机上 这样可以在笔记本上使用…...

BUUCTF---[极客大挑战 2019]BabySQL1
1.这道题和之前做的几道题是相似的,这道题考的知识点更多。难度也比之前的大一些 2.尝试万能密码 or 1#发现过滤了or,使用1和1,发现他对单引号也进行了过滤。于是我尝试进行双写绕过,发现可以通过了。 3.由之前的做题经验可知,这道题会涉及到…...

0基础跨考计算机|408保姆级全年计划
我也是零基础备考408! 虽说是计算机专业,但是本科一学期学十几门,真的期末考试完脑子里什么都不进的...基本都是考前一周发疯学完水过考试...😅 想要零基础跨考可以直接从王道开始!跟教材一点一点啃完全没必要🥸 现在…...

C# 操作LiteDB
1、很简单的东西不废话,直接上图上代码。 2、NuGet程序中根据自己的项目版本安装LiteDB,如下图: 3、程序运行加过如下图: 4、程序代码如下: using System; using System.Collections.Generic; using System.Linq; using System…...

LeetCode 2917.找出数组中的 K-or 值:基础位运算
【LetMeFly】2917.找出数组中的 K-or 值:基础位运算 力扣题目链接:https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有…...

MySQL窗口函数:从理论到实践
目录 1. ROW_NUMBER() 2. RANK() 3. DENSE_RANK() 4. NTILE(n) 5. LAG() 和 LEAD() 6. FIRST_VALUE() 和 LAST_VALUE() 总结 MySQL中的窗口函数(Window Functions)允许用户对一个结果集的窗口(或分区)执行计算,…...

Vue+SpringBoot打造考研专业课程管理系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…...

python基础第二天
世界杯小组赛成绩 注意: 1.循环 1.1while 1.2for 1.3 range 1.4 while else while 循环正常执行完才能执行else语句...

YOLOV9论文解读
代码:https://github.com/WongKinYiu/yolov9论文:https://arxiv.org/abs/2402.1361本文提出可编程梯度信息(PGI)和基于梯度路径规划的通用高效层聚合网络(GELAN),最终铸成YOLOv9目标检测全新工作!性能表现SOTA!在各个方…...

【Spring】21 通过@Primary注解优化注解驱动的自动装配
文章目录 Primary注解简介优势和适用场景小结 Spring 框架提供了强大的依赖注入机制,其中 Autowired 注解是一种常用的方式。然而,当存在多个候选 bean 时,通过类型自动装配可能导致选择困难。为了更好地控制这一过程,Spring 引入…...

【HTML】HTML基础7.3(自定义列表)
目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…...

java设计模式课后作业(待批改)
此文章仅记录学习,欢迎各位大佬探讨 实验(一) 面向对象设计 实验目的 ①使用类来封装对象的属性和功能; ②掌握类变量与实例变量,以及类方法与实例方法的区别; 知识回顾 详情见OOP课件 实验内容…...

qt 语音引擎 QTextToSpeech Microsoft SAPI
QT中语音播报的代码 在QT中实现语音播报可以使用QTextToSpeech类,具体代码如下: #include <QCoreApplication> #include <QTextToSpeech> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创…...

react hook: useimperativeHandle
通过 useImperativeHandle,子组件可以选择性地暴露给父组件某些属性或方法,而不是将所有属性和方法暴露出去。 父组件 获得自组件的 ref,就能通过该 ref 来调用 focus来聚焦等功能 在 forwardRef 包装的组件中,ref 固定地是第二个…...

30天自制操作系统(第28天)
28.1 alloca __alloca 会在下述情况下被 C 语言的程序调用(采用 near-CALL 的方式)。 1、要执行的操作从栈中分配 EAX 个字节的内存空间( ESP - EAX; ) 2、要遵守的规则不能改变 ECX 、 EDX 、 EBX 、 EBP 、 ESI 、 EDI的值&am…...

Nginx启动服务
Nginx启动服务 一、启动前置 下载地址 如已安装Docker,下一步拉取Nginx最新的Docker镜像: docker pull nginx:latest查看拉取下来的镜像: docker images二、启动服务 创建Docker容器: docker run --name {projectname} -p 80…...

coqui-ai/TTS 案例model文件
GitHub - coqui-ai/TTS: 🐸💬 - a deep learning toolkit for Text-to-Speech, battle-tested in research and production Coqui AI的TTS是一款开源深度学习文本转语音工具,以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&…...

如何利用API接口进行高效的商品变体管理?
要利用API接口进行高效的商品变体管理,您需要执行一系列策略和技术步骤来确保数据的准确性和实时性。以下是详细的指南: 1. 确定变体管理需求 分析产品:识别具有变体的产品,并明确这些变体的属性(如尺寸、颜色、材质…...

扼杀网络中的环路:STP、RSTP、MSTP
目录 前言: 一、STP(Spanning Tree Protocol) 1.1 STP功能 1.2 STP应用 二、RSTP(Rapid Spanning Tree Protocol) 2.1 RSTP功能 2.2 RSTP应用 三、MSTP(Multiple Spanning Tree Protocol࿰…...

青少年如何从零开始学习Python编程?有它就够了!
文章目录 写在前面青少年为什么要学习编程 推荐图书图书特色内容简介 推荐理由粉丝福利写在最后 写在前面 本期博主给大家带来一本非常适合青少年学习编程的图书,快来看看吧~ 青少年为什么要学习编程 青少年学习编程,就好比在他们年轻时就开始掌握一种…...

触发HTTP preflight预检及跨域的处理方法
最近在做需求的过程中,遇到了很多跨域和HTTP预检的问题。下面对我所遇到过的HTTP preflight和跨域的相关问题进行总结: 哪些情况会触发HTTP preflight preflight属于cors规范的一部分,在有跨域的时候,在一定情况下会触发preflig…...

【算法可视化】搜索算法专题
运行平台 Algorithm Visualizer 选数 [NOIP2002 普及组] 选数 // 导入可视化库 { const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } require(algorithm-visualizer); // }const N 4, K 3; //从包含4个元素的集合中选出3个数 let ans 0 //方案数 co…...

编写dockerfile挂载卷、数据容器卷
编写dockerfile挂载卷 编写dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…...

理解OAuth 2.0
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为RFC 6749。 一、应用场景 为了…...

8. Go实现Gin服务优雅关机与重启
文章目录 优雅关机优雅重启 无论是优雅关机还是优雅重启归根结底都是通过监听特定系统信号,然后执行一定的逻辑处理保障当前系统正在处理的请求被正常处理后再关闭当前进程。 优雅关机 优雅关机就是服务端关机命令发出后不是立即关机,而是等待当前还在…...

SQL 注入攻击 - cookie base64编码注入
环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、Base64编码介绍 原理 Base64编码的原理是将三个字节的二进制数据(共24位)转换成四个ASCII字符。由于每个ASCII字符可以表示64种状态(2^6),刚好可以用来表示24位二进制数…...