Java对象的序列化和反序列化实践

Java对象的序列化和反序列化实践
Java对象的序列化和反序列化实践

Java对象的序列化和反序列化实践

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

把Java对象转换为字节序列的过程称为对象的序列化。

把字节序列恢复为Java对象的过程称为对象的反序列化。

对象的序列化主要有两种用途:

1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

2)在网络上传送对象的字节序列。

一.JDK类库中的序列化API

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。

对象序列化包括如下步骤:

1)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

2)通过对象输出流的writeObject()方法写对象。

对象反序列化的步骤如下:

1)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

2)通过对象输入流的readObject()方法读取对象。

下面让我们来看一个对应的例子,类的内容如下:

import java.io.*;

import java.util.Date;

/**

* 对象的序列化和反序列化测试类.

* @author AmigoXie * @version 1.0

* Creation date: 2007-9-15 - 下午21:45:48

*/

public class ObjectSaver {

/**

* @param args

* @author AmigoXie * Creation date: 2007-9-15 - 下午21:45:37

*/

public static void main(String[] args) throws Exception { ObjectOutputStream out = new ObjectOutputStream

(new FileOutputStream("D:""objectFile.obj"));

//序列化对象

Customer customer = new Customer("阿蜜果", 24);

out.writeObject("你好!");

out.writeObject(new Date());

out.writeObject(customer);

out.writeInt(123); //写入基本类型数据

out.close();

//反序列化对象

ObjectInputStream in = new ObjectInputStream

(new FileInputStream("D:""objectFile.obj"));

System.out.println("obj1=" + (String) in.readObject());

System.out.println("obj2=" + (Date) in.readObject());

Customer obj3 = (Customer) in.readObject();

System.out.println("obj3=" + obj3);

int obj4 = in.readInt();

System.out.println("obj4=" + obj4);

in.close();

}

}

class Customer implements Serializable {

private String name;

private int age;

public Customer(String name, int age) {

https://www.360docs.net/doc/6012703060.html, = name;

this.age = age;

}

public String toString() {

return "name=" + name + ", age=" + age;

}

}

输出结果如下:

obj1=你好!

obj2=Sat Sep 15 22:02:21 CST 2007

obj3=name=阿蜜果, age=24

obj4=123

因此例比较简单,在此不再详述。

二.实现Serializable接口

ObjectOutputStream只能对Serializable接口的类的对象进行序列化。默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量。

当ObjectOutputStream按照默认方式反序列化时,具有如下特点:

1)如果在内存中对象所属的类还没有被加载,那么会先加载并初始化这个类。如果在classpath中不存在相应的类文件,那么会抛出ClassNotFoundException;

2)在反序列化时不会调用类的任何构造方法。

如果用户希望控制类的序列化方式,可以在可序列化类中提供以下形式的writeObject()和readObject()方法。

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException,

ClassNotFoundException;

当ObjectOutputStream对一个Customer对象进行序列化时,如果该对象具有writeObject()方法,那么就会执行这一方法,否则就按默认方式序列化。在该对象的writeObjectt()方法中,可以先调用ObjectOutputStream的defaultWriteObject()方法,使得对象输出流先执行默认的序列化操作。同理可得出反序列化的情况,不过这次是defaultReadObject()方法。

有些对象中包含一些敏感信息,这些信息不宜对外公开。如果按照默认方式对它们序列化,那么它们的序列化数据在网络上传输时,可能会被不法份子窃取。对于这类信息,可以对它们进行加密后再序列化,在反序列化时则需要解密,再恢复为原来的信息。

默认的序列化方式会序列化整个对象图,这需要递归遍历对象图。如果对象图很复杂,递归遍历操作需要消耗很多的空间和时间,它的内部数据结构为双向列表。

在应用时,如果对某些成员变量都改为transient类型,将节省空间和时间,提高序列化的性能。

三.实现Externalizable接口

Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

前者负责序列化操作,后者负责反序列化操作。

在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException:

no valid constructor异常。

四.可序列化类的不同版本的序列化兼容性

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。

类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高哦啊serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:

1)在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;

2)在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

java序列化的作用

最近在阅读Core J2EE Patterns 的时候发现例子里用于在各个层次里进行传输的TO(Data Transfer Object)都实现了java.io.Serializable接口,看到这些偶突然感到茅塞顿开~困扰了很久的关于Serializable的疑问渐渐解开了,查找相关资料并总结如下: 序列化是什么: 序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。 序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例 序列化的什么特点: 如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。 什么时候使用序列化: 一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。 二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。 ====================== 可以看看接口java.io.serializable的中文解释: Serializable public interface Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

WebLogic 组件反序列化漏洞补丁升级操作手册

weblogic反序列化补丁安装 梁裕 1、到weblogic官网下载补丁包(p2*******_1036_Generic.zip、 p2*******_1036012_Generic.zip如果找不到的朋友,可以在回复中给我留下邮箱,我会定期回复。) 2、10.3.6对应的补丁包p2*******_1036012_Generic.zip ,补丁包需要依赖于一个大的升级 包,所以需要把p2*******_1036_Generic.zip也下载下来。 3、登录linux的weblogic用户,切换到/home/weblogic/Oracle/Middleware/utils/bsu/目录下。 4、确认当前weblogic版本,并确认所有域的进程全部关闭 ./bsu.sh -prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3/ -status=applied -verbose –view 5、查看是否存在/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir 目录,没有的需要 手工创建。 6、将补丁包上传到/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir目录下 7、首先打大的升级包,解压p2*******_1036_Generic.zip unzip p2*******_1036_Generic.zip EJUW对应就是后面命令的patchlist 8、执行补丁安装命令。 ./bsu.sh -install -patch_download_dir=/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir -patchlist=EJUW-prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3 –verbose 9、打序列化的补丁包,解压p2*******_1036012_Generic.zip unzip p2*******_1036012_Generic.zip ./bsu.sh -install -patch_download_dir=/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir -patchlist=ZLNA-prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3 –verbose 10、在打ZLNA补丁包时,遇到了内存溢出的问题。需要修改bsu.sh脚本,将内存调大。 11、启动weblogic的域,查看输出日志。确定版本是否生效。

C++序列化反序列化库Kapok

C++序列化/反序列化库Kapok 1.Kapok的特点 简单,易用,header-only,只需要引用Kapok.hpp即可;高效,初步测试性和messagepack 相当。 它是纯c++11实现,因此需要支持C++11的编译器。 2.主要功能 对对象进行自动化的序列化和反序列化,用起来非常简单,先来看个序列化/反序列化一个tuple的例子吧。 //序列化 Serializer sr; auto tp = std::make_tuple(10, 12, string("test")); sr.Serialize(tp, "tuple"); //反序列化 DeSerializer dr; std::tuple p; dr.Parse(sr.GetString()); dr.Deserialize(p, "tuple"); 看起来是不是很简单! 再看一个序列化一个自定义对象的例子。 struct Person { int age; string name; string city; META(age, name, city) }; Person p = { 18, "bb", "aa" }; //序列化 Serializer sr; sr.Serialize(p, "Person"); //反序列化 DeSerializer dr;

Person person; dr.Parse(sr.GetString()); dr.Deserialize(person, "Person"); 一样的很简单,结构这里需要一个宏定义META,这个META的作用就是获取对象的元信息,有了这个元信息我们就可以很方便的实现序列化和反序列化了。 3.应用场景 Kapok除了不支持指针之外所有的对象都支持,支持结构体的无限嵌套(被嵌套的结构体也必须定义META宏)。这里说一下为什么不支持指针呢,因为对象中有指针的话存在两个问题:1.这个指针如果是动态数组的话,c++中无法获取这个数组的长度;2.指针还涉及到内存管理,我希望Kapok专注于序列化和/反序列化,暂时不考虑内存管理。 4.结构体必须有一个宏定义是否具有侵入性? 看起来每个序列化/反序列化的对象都要带一个宏定义似乎侵入性较强,但这种侵入性是完全无害的,因为它只是定义了一个额外的函数而已,这个函数只会在序列化/反序列化的时候才会用到,不会对当前对象造成任何影响,还有一点是因为c++没有反射,必须要通过某种方法来获取对象的元信息,纵观目前所有的序列化方案,只有这种方式是最简洁的,用户做最少的事情即可,这也是我选择这种方式的原因。 5.Kapok是如何实现序列化/反序列化的 Kapok的最底层是用到了rapidjson, 用它来实现对基本类型的序列化,对它做了一个简单的封装以便供上层使用,上面层就是序列化\反序列化实现层,主要是实现对对象元信息的解析和自动化的打包和解包。下面是Kapok序列化的一个示意图: 6.Kapok的性能如何 初步测试对一个tuple进行序列化/反序列化一万次,发现Kapok的耗时和messagepack相当。 7.Kapok是否支持多语言 暂时不支持,先把c++版本做好再说,如果要支持多语言的话,需要用其它语言进行重写,

JAVA序列化基础知识Serializable与Externalizable的区别

大家都知道Serializable是一个mark interface,告诉JVM这个对象可以被转换成二进制流来传输. 但是Serializable与Externalizable的转换二进制流的过程是不一样的. Serializable 在我们实现这个接口的时候,我们可以使用4个私有方法来控制序列化的过程: 我们来看一个例子: public class FooImpl implements java.io.Serializable{ private String message; public String getFoo() { return message; } public void setMessage(String message) { this.message = message; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { System.out.println("writeObject invoked"); out.writeObject(this.message == null ? "hohohahaha" : this.message); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { System.out.println("readObject invoked"); this.message = (String) in.readObject(); System.out.println("got message:" + message); } private Object writeReplace() throws ObjectStreamException { System.out.println("writeReplace invoked"); return this; } private Object readResolve() throws ObjectStreamException { System.out.println("readResolve invoked"); return this; }

Java-Jackson反序列化漏洞及挖洞思路

源码分析Jackson反序列化漏洞 前言: 本次分析从Java序列化和反序列化源码开始分析,进一步分析Jackson源码,找出造成漏洞的原因,最后以Jackson2.9.2版本,JDK1.80_171,resin4.0.52,CVE-2020-10673为例复现漏洞。 一.JA V A反序列化原理 1.1 Class对象 每一个类都有一个Class对象,Class对象包含每一个类的运行时信息,每一个类都有一个Class对象,每编译一个类就产生一个Class对象,Class类没有公共的构造方法,Class对象是在类加载的时候由JVM以及通过调用类加载器中的DefineClass()方法自动构造的,因此不能显式地声明一个Class对象。在类加载阶段,类加载器首先检查这个类的Class对象是否已经被加载。如果尚未加载,默认的类加载器就会根据类的全限定名查找.class文件。一旦某个类的Class对象被载入内存,我们就可以它来创建这个类的所有对象以及获得这个类的运行时信息。 获得Class对象的方法: 1).Class.forName(“类的全名”);//com.xx.xx.xx 2).实例对象.getClass() 3).类名.class 1.2反射 JA V A反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

实现Java反射机制的类都位于https://www.360docs.net/doc/6012703060.html,ng.reflect包中: 1).Class类:代表一个类 2).Field类:代表类的成员变量(类的属性) 3).Method类:代表类的方法 4).Constructor类:代表类的构造方法 5).Array类:提供了动态创建数组,以及访问数组的元素的静态方法 简单反射调用代码 Class clz=this.getClass(); Object obj= clz.getMethod("方法名",Class对象序列).invoke(this,Object参数序列); 1.3 反序列化 Java 序列化是指把Java 对象转换为字节序列的过程便于保存在内存、文件、数据库中,ObjectOutputStream类的writeObject() 方法可以实现序列化。 Java 反序列化是指把字节序列恢复为Java 对象的过程,ObjectInputStream 类的readObject() 方法用于反序列化。 RMI:是Java 的一组拥护开发分布式应用程序的API,实现了不同操作系统之间程序的方法调用。值得注意的是,RMI 的传输100% 基于反序列化,Java RMI 的默认端口是1099 端口。 JMX:JMX 是一套标准的代理和服务,用户可以在任何Java 应用程序中使用这些代理和服务实现管理,中间件软件WebLogic 的管理页面就是基于JMX 开发的,而JBoss 则整个系统都基于JMX 构架。 只有实现了Serializable接口的类的对象才可以被序列化,Serializable 接口是启用其序列化功能的接口,实现java.io.Serializable 接口的类才是可序列化的,没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化。 readObject() 方法的作用正是从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回,readObject() 是可以重写的,可以定制反序列化的一些行为。 readObject()主要做的事情,其实就是读取正常应该被序列化的字段信息后,

将php序列化到数据库的对象饭序列化成java对象

将php序列化到数据库的对象饭序列化成java对象 php的对象序列化到数据库中,形如 a:3:{i:0;i:1241;i:1;i:4;i:2;i:16;}但是java需要取出这样的对象,转换成java的对象/* PHPSerializer.java * * Author: Ma Bingyao * Copyright: https://www.360docs.net/doc/6012703060.html, * Version: 2.1 * LastModified: 2006-08-09 * This library is free. You can redistribute it and/or modify it. * https://www.360docs.net/doc/6012703060.html,/?p=202 */ package org.phprpc.util; import java.io.*; import java.util.*; import https://www.360docs.net/doc/6012703060.html,ng.reflect.*;

class UnSerializeResult { public Object value; public int hv; public UnSerializeResult() {} public UnSerializeResult(Object value, int hv) { this.value = value; this.hv = hv; } } public class PHPSerializer { private static Package[] __packages = Package.getPackages(); private static final byte __Quote = 34; private static final byte __0 = 48; private static final byte __1 = 49; private static final byte __Colon = 58; private static final byte __Semicolon = 59; private static final byte __C = 67; private static final byte __N = 78;

使用json-lib完成json的序列化和反序列化

使用json-lib完成json的序列化和反序列化2011-07-29 14:07:43 分类:默认分类 | 标签:软件 java json. json的序列化和反序列化在现在的javaweb中特别是ajax中使用的比较频繁,现在本人就这种技术提出自己的使用心得。 我的pojo对象的结构是这样的 部门表和员工表 1对多的关系 部门对象 public class Dept implements java.io.Serializable { private Integer depid;//部门ID private String depname;//部门名称 private Set emps = new HashSet(0);//员工集合 } 员工对象 public class Emp implements java.io.Serializable { private Integer empid;//员工id private Dept dept;//部门 private String empname;//员工名称 private Date birthday;//生日 } 1.json字符串序列化成对象 /** *通过json转换成对象 *@author凤生禾予 */ public void jsonToObject(){ Date d=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); StringBuffer str=new StringBuffer(); // json字符串 str.append("{empid:1,dept:{depid:1,depname:'开发部'},empname:'张三 ',birthday:'"+sdf.format(d)+"'}"); // 使用JSONObject将json序列化对象 JSONObject obj=JSONObject.fromObject(str.toString()); // 将JOSNObject对象转换成pojo对象 Emp emp=(Emp) JSONObject.toBean(obj,Emp.class); System.out.println(emp.getBirthday()); } 这里需要注意的是json字符串的写法以{}表示一个对象,字符串必须加引号

CVE-2009-0658漏洞分析

CVE-2009-0658漏洞分析 题目:CVE-2009-0658漏洞分析 原作:Peter Kleissner (http://web17.webbpro.de/index.php?page=analysing-the-pdf-exploit) 翻译:Cryin' 我想给大家分享下2009年3月对一个Adobe pdf漏洞的分析结果,该漏洞由于JBIG2压缩中的BUG导致执行任意Win32代码。该漏洞目前(2009年3月3日)已经仅在内部被修补,但Adobe有望在3月11日才发布更新版本。自2007年以来的所有Adobe阅读器(Adobe Reader 7.0和更高版本都受影响),恶意PDF文件利用此漏洞的成功率非常低,所以传播的不是很广泛。 PDF文件概览 首先让我们大概的认识下一般的PDF恶意文件 ?JavaScript代码,使Exploit成为可能 ?Shellcode集成在JavaScript代码中(加载在Stream里面) ?Exploit Code,包含在PDF文件的Stream中并经过加密的可执行文件(malware) ?伪造的PDF文件,实现隐藏的目的 PDF漏洞文件开发主要有三个部分:JavaScript代码、Shellcode、Exploit Code。这三部分在漏洞利用开发过程中都同等重要。 Pidief是一个知名度很高、传播十分广泛的病毒家族(本文分析的也是),在其历史上它利用各种Adobe Pdf漏洞来执行恶意程序(malware).下面分析的就是Pidief家族中鲜活的实例。尽情享受吧! JavaScript代码 Pidief包含的第一段JavaScript代码作为脚本存储在PDF文件的Object对象中,代码经过八进制编码后如下面所示: 2 0 obj <

java序列化原理与算法

Java序列化原理和算法 总结: java中序列化算法的顺序: 1、子类的类信息描述 2、子类的字段信息描述(如果遇到类对象的属性,暂时用string的指针表示) 3、父类的类信息描述 4、父类的字段信息描述 5、对父类的字段信息进行赋值 6、对子类的字段信息进行赋值 7、发现子类的字段为类对象时,描述该类对象,并查找该类对象的父类,以以上方式描述,然后赋值。 本文讲解了Java序列化的机制和原理。从文中你可以了解如何序列化一个对象,什么时候需要序列化以及Java序列化的算法。 有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。 Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization 是一种将这些字节重建成一个对象的过程。Java序列化API提供一种处理对象序列化的标准机制。在这里你能学到如何序列化一个对象,什么时候需要序列化以及Java序列化的算法,我们用一个实例来示范序列化以后的字节是如何描述一个对象的信息的。 序列化的必要性 Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。 这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。如何序列化一个对象 一个对象能够序列化的前提是实现Serializable接口,Serializable接口没有方法,更像是个标记。 有了这个标记的Class就能被序列化机制处理。 import java.io.Serializable; class TestSerial implements Serializable { public byte version = 100; public byte count = 0; } 然后我们写个程序将对象序列化并输出。ObjectOutputStream能把Object输出成Byte流。 我们将Byte流暂时存储到temp.out文件里。 public static void main(String args[]) throws IOException { FileOutputStream fos = new FileOutputStream("temp.out");

Django任意代码执行漏洞分析

Django任意代码执行漏洞分析 从Django的SECTET_KEY到代码执行 Django是一个可以用于快速搭建高性能,优雅的网站的平台,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS (内容管理系统)软件。并于2005年7月在BSD许可证下发布。 最近在进行网站代码审查的过程中,发现某些产品由于session使用不当,导致可能被攻击者利用,执行任意代码。这些产品在登录的JS代码中,泄露了SECRET_KEY,将该值作为密码加密的盐,这样就暴露了加密salt不太好吧,更重要的是对django的安全造成了极大的威胁。 2 SECRET_KEY作用 SECTET_KEY在djanog中使用非常广泛,基本上涉及到安全,加密等的地方都用到了,下面列举一些常见情景:1,json object的签名2,加密函数,如密码重置,表单,评论,csrf的key,session数据 这里面就要重点讲到session的问题,在这里使用不当就会导致代码执行

3 代码执行 3.1 settings的session设置 django默认存储session到数据库中,但是可能会比较慢,就会使用到缓存,文件,还有cookie等方式,如果采用了cookie机制则有可能代码执行,settings配置如下: SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' 3.2 django 1.6以下 在django1.6以下,session默认是采用pickle执行序列号操作,在1.6及以上版本默认采用json序列化。代码执行只存在于使用pickle序列话的操作中。 3.3 session处理流程 可以简单的分为两部分,process_request和process_response,前者负责选择session引擎,初始化cookie 数据。见代码 Python class SessionMiddleware(object): def process_request(self, request): engine = import_module(settings.SESSION_ENGINE) session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME,

Java序列化的机制和原理

Java序列化的机制和原理 有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。 Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization 是一种将这些字节重建成一个对象的过程。Java序列化API提供一种处理对象序列化的标准机制。在这里你能学到如何序列化一个对象,什么时候需要序列化以及Java序列化的算法,我们用一个实例来示范序列化以后的字节是如何描述一个对象的信息的。 序列化的必要性 Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。 如何序列化一个对象 一个对象能够序列化的前提是实现Serializable接口,Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。 1.import java.io.Serializable; 2. 3.class TestSerial implements Serializable { 4. 5.public byte version = 100; 6. 7.public byte count = 0; 8. 9.} 然后我们写个程序将对象序列化并输出。ObjectOutputStream能把Object输出成Byte 流。我们将Byte流暂时存储到temp.out文件里。 1.public static void main(String args[]) throws IOException { 2. 3. FileOutputStream fos = new FileOutputStream("temp.out "); 4. 5. ObjectOutputStream oos = new ObjectOutputStream(fos); 6. 7. TestSerial ts = new TestSerial();

Struts S2-045 漏洞调试及分析

Struts S2-045漏洞调试及分析 Auth:Cryin’ Date:2016.3.9 漏洞公告 首先看官方给出的漏洞公告信息: “Possible Remote Code Execution when performing file upload based on Jakarta Multipart parser.” 问题原因: “It is possible to perform a RCE attack with a malicious Content-Type value. If the Content-Type value isn't valid an exception is thrown which is then used to display an error message to a user.” 从公告信息可以得到几个漏洞的重点信息: ●存在漏洞的模块是Jakarta ●漏洞产生的点是恶意的Content-Type头 ●恶意的Content-Type头会造成程序抛出异常,在显示错误消息给用户时造成RCE 补丁对比 查看Struts2版本2.3.32在github上的commit(Uses default error key if specified key doesn't exist)并对比修改内容: https://https://www.360docs.net/doc/6012703060.html,/apache/struts/commit/352306493971e7d5a756d61780d57a76eb1 f519a 可以看到对LocalizedTextUtil.findText方法进行了重写,并添加了判断。Struts2RCE漏洞的根本原因是程序将用户可控数据带入OGNL表达式解析并执行,而OGNL(Object Graph Navigation Language)对象图形导航语言是一个功能强大的表达式语言,可以用来获取和设置Java对象的属性,但同时也可以对服务端对象进行修改,绕过沙盒甚至可以执行系统命令。 所以,从补丁分析来看LocalizedTextUtil.findText函数很可能是OGNL表达式的传入点,在调试分析时可在此处下断点跟踪分析。 关于jakarta Jakarta是struts2默认处理multipart报文的解析器,该组件定义在struts-default.xml中: 默认使用org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类对上传数据进行解析并调用第三方组件commons-fileupload.jar完成上传操作。

java序列化的作用

1、序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。 2、什么情况下需要序列化 a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候; b)当你想用套接字在网络上传送对象的时候; c)当你想通过RMI传输对象的时候; 3、当对一个对象实现序列化时,究竟发生了什么? 在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如: java 代码 1.Foo myFoo = new Foo(); 2.myFoo .setWidth(37); 3.myFoo.setHeight(70); 当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(3 7,70)都被保存到foo.ser文件中,这样以后又可以把它从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对象。 java 代码 1.FileOutputStream fs = new FileOutputStream("foo.ser"); 2.ObjectOutputStream os = new ObjectOutputStream(fs); 3.os.writeObject(myFoo); 4、实现序列化(保存到一个文件)的步骤 a)Make a FileOutputStream

2018年网络安全状况及2019年网络安全趋势

第35卷 第2期 福 建 电 脑 Vol. 35 No.2 2019年2月 Journal of Fujian Computer Feb. 2019 ——————————————— 刘娟(通信作者),女,1989年生,主要研究领域为网络安全技术.E-mail:liujuan@https://www.360docs.net/doc/6012703060.html,. 2018年网络安全状况及2019年网络安全趋势 刘娟 (国家计算机网络应急技术处理协调中心福建分中心 福州 350002) 摘 要 为了总结2018年我国网络安全总体状况及特点,研判2019年需重点关注的网络安全趋势,本文基于监测数据和开源情报,分别从恶意软件、数据安全、物联网安全、APT 攻击等方面梳理了2018年我国网络安全六大态势,提出了物联网安全风险加大、恶意软件更加多样化、供应链攻击持续发生、信息泄露推动技术能力提升等四点网络安全趋势。 关键词 网络安全;物联网;勒索病毒;信息泄露 中图法分类号 TP393.08 The Cyber Security Situation in 2018 and Its Trends in 2019 LIU Juan (The Computer Network Emergency Response Technical Team/Coordination Center of Fujian, Fuzhou, China, 350002) 1 网络安全现状 2018年以来,我国网络安全态势持续严峻,勒索病毒、DDOS 攻击、挖矿病毒、信息泄露、APT 攻击等各类网络安全威胁层出不穷。笔者根据监测数据和开源情报对六类典型网络安全威胁态势和特点进行分析总结。 1.1 勒索病毒 自2017年5月WannaCry 勒索病毒事件爆发以来,各类勒索病毒此起彼伏。2018年,我国多家医院、学校、行政服务中心、企业等被曝感染勒索病毒[1],造成极大危害。一方面,Globelmposter 、GandCrab 、Satan 等各类勒索病毒十分活跃,呈现更新快、变种多的特点。以GandCrab 勒索病毒为例,该勒索病毒于2018年1月首次被发现,截至目前已监测发现5个大版本升级,每个大版本还包含多个变种。另一方面,与WannaCry “广撒网”式投毒不同,2018年勒索病毒主要以重要行业重要数据服务器为目标,实现“精准投毒”,以期获得 更多赎金。攻击者往往通过暴力破解、漏洞利用等手段突破受害网络边界后部署勒索病毒。监测数据显示,福建省2018年受感染行业分布如图1所示, 可以看出政府部门是感染勒索病毒的重灾区。 图1 福建省2018年勒索病毒事件受害行业分析 1.2 信息泄露 2018年,互联网上曝光了多起我国公民信息泄露事件,泄露数据高达数十亿条,数据来源包括连锁酒店、快递公司、视频网站、求职网站等。例如,2018年8月,华住旗下多家连锁酒店5亿条用户个人信息及入住记录在暗网公开叫卖,标价8个比特币(约合人民币35万元)。与以往相比,暗网数据售卖成为此类事件曝光的主渠道。究其原因是随着我国《网络安全法》的实施,对个人信息保护越来越完善,攻击者为了隐藏行踪转而在暗网通过加密货币进行交易。这些信息泄露事件暴露了部分掌握

Java对象的序列化和反序列化实践

Java对象的序列化和反序列化实践 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。 把Java对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为Java对象的过程称为对象的反序列化。 对象的序列化主要有两种用途: 1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 2)在网络上传送对象的字节序列。 一.JDK类库中的序列化API java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、 只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。 对象序列化包括如下步骤: 1)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流; 2)通过对象输出流的writeObject()方法写对象。 对象反序列化的步骤如下: 1)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

Struts2漏洞利用原理及OGNL机制研究

Struts2漏洞利用原理及OGNL机制研究 Auth:Cryin’ Date:2015.04.19 概述 在MVC开发框架中,数据会在MVC各个模块中进行流转。而这种流转,也就会面临一些困境,就是由于数据在不同MVC层次中表现出不同的形式和状态而造成的: ◆View层—表现为字符串展示 数据在页面上是一个扁平的、不带数据类型的字符串,无论数据结构有多复杂,数据类型有多丰富,到了展示的时候,全都一视同仁的成为字符串在页面上展现出来。数据在传递时,任何数据都都被当作字符串或字符串数组来进行。 ◆Controller层—表现为java对象 在控制层,数据模型遵循java的语法和数据结构,所有的数据载体在Java世界中可以表现为丰富的数据结构和数据类型,你可以自行定义你喜欢的类,在类与类之间进行继承、嵌套。我们通常会把这种模型称之为复杂的对象树。数据在传递时,将以对象的形式进行。 可以看到,数据在不同的MVC层次上,扮演的角色和表现形式不同,这是由于HTTP协议与java的面向对象性之间的不匹配造成的。如果数据在页面和Java世界中互相传递,就会显得不匹配。所以也就引出了几个需要解决的问题: 1.当数据从View层传递到Controller层时,我们应该保证一个扁平而分散在各处的数据集合能以一定的规则设置到Java世界中的对象树中去。同时,能够灵活的进行由字符串类型到Java中各个类型的转化。 2.当数据从Controller层传递到View层时,我们应该保证在View层能够以某些简易的规则对对象树进行访问。同时,在一定程度上控制对象树中的数据的显示格式。 我们稍微深入思考这个问题就会发现,解决数据由于表现形式的不同而发生流转不匹配的问题对我们来说其实并不陌生。同样的问题会发生在Java世界与数据库世界中,面对这种对象与关系模型的不匹配,我们采用的解决方法是使用如hibernate,iBatis等框架来处理java对象与关系数据库的匹配。 现在在Web层同样也发生了不匹配,所以我们也需要使用一些工具来帮助我们解决问题。为了解决数据从View层传递到Controller层时的不匹配性,Struts2采纳了XWork的一套完美方案。并且在此的基础上,构建了一个完美的机制,从而比较完美的解决了数据流转中的不匹配性。就是表达式引擎OGNL。它的作用就是帮助我们完成这种规则化的表达式与java对象的互相转化(以上内容参考自Struts2技术内幕)。 关于OGNL OGNL(Object Graph Navigation Language)即对象图形导航语言,是一个开源的表达式引擎。使用OGNL,你可以通过某种表达式语法,存取Java对象树中的任意属性、调用Java 对象树的方法、同时能够自动实现必要的类型转化。如果我们把表达式看做是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。我们可以轻松解决在数据流转过程中所遇到的各种问题。 OGNL进行对象存取操作的API在Ognl.java文件中,分别是getValue、setValue两个方法。getValue通过传入的OGNL表达式,在给定的上下文环境中,从root对象里取值:

《JAVA面向对象编程》([PDF] 孙卫琴著)

《JAVA面向对象编程》[PDF] 孙卫琴著 【目录】 第1章面向对象开发方法概述 1 1.1 结构化的软件开发方法简介3 1.2 面向对象的软件开发方法简介5 1.2.1 对象模型6 1.2.2 UML:可视化建模语言6 1.2.3 Rational Rose:可视化建模工具7 1.3 面向对象开发中的核心思想和概念7 1.3.1 问题领域、对象、属性、状态、行为、方法、实现7 1.3.2 类、类型9 1.3.3 消息、服务10 1.3.4 接口11 1.3.5 封装、透明12 1.3.6 抽象16 1.3.7 继承、扩展、覆盖17 1.3.8 组合19 1.3.9 多态、动态绑定22 1.4 UML语言简介24 1.4.1 用例图24 1.4.2 类框图25 1.4.3 时序图26 1.4.4 协作图27 1.4.5 状态转换图27 1.4.6 组件图28 1.4.7 部署图29 1.5 类之间的关系29 1.5.1 关联(Association)29 1.5.2 依赖(Dependency)31 1.5.3 聚集(Aggregation)31 1.5.4 泛化(Generalization)32 1.5.5 实现(Realization)32 1.5.6 区分依赖、关联和聚集关系33 1.6 实现Panel系统35 1.6.1 扩展Panel系统37 1.6.2 用配置文件进一步提高Panel系统的可维护性39 1.6.3 运行Panel系统40 1.7 小结41 1.8 思考题42 第2章第一个Java应用43 2.1 创建Java源文件43 2.1.1 Java源文件结构44

相关文档
最新文档