序列化揭秘(一)

   声明:因为准备在项目组内部做一次关于序列化的分享,故有如此一系列关于序列化的博文产生。次系列期间参考了一些其他的资料,如《java加密与解密的艺术》,java官方序列化规范文档等资料,来源相对较杂,在此不一一说明,后续也不再说明。仅致以最诚挚的感谢!此为原创,转载请说明出处   -----哲渊2011-4-10

 

   序列化的二进制数据几乎是以明文的形式在网络传输,这样会存在比较大的安全问题。解决方案之一如下:

对整个对象进行加密和签名,最简单的是将它放在一个 javax.crypto.SealedObject  或 java.security.SignedObject 包装器中。两者都是可序列化的,所以将对象包装在 SealedObject 中可以围绕原对象创建一种 “包装盒”。必须有对称密钥才能解密,而且密钥必须单独管理。同样,也可以将 SignedObject 用于数据验证,并且对称密钥也必须单独管理。以下代码解释了以SignedObject为例说明如何进行整个对象的序列化安全加密和解密。

 

需要序列化的原始类代码:

package zheyuan.experiment4.com;

import java.io.Serializable;

/**
 * 用于被密钥包装的类
 * 
 * @author Administrator
 * 
 */
public class SignedPerson implements Serializable {

	private static final long serialVersionUID = 8533862948800025300L;

	private String name;
	private int age;
	private boolean isNB;

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public boolean isNB() {
		return isNB;
	}

	public void setNB(boolean isNB) {
		this.isNB = isNB;
	}

}



序列化类的加密解密类代码如下:

package zheyuan.experiment4.com;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.SignedObject;

public class SignedSerializableTest {

	/**
	 *    如果需要对整个对象进行加密和签名,最简单的是将它放在一个 javax.crypto.SealedObject 
	 *    或 java.security.SignedObject 包装器中。两者都是可序列化的,所以将对象包装在 SealedObject 
	 *    中可以围绕原对象创建一种 “包装盒”。必须有对称密钥才能解密,而且密钥必须单独管理。
	 *    同样,也可以将 SignedObject 用于数据验证,并且对称密钥也必须单独管理。 
	 *    
	 *    这里以SignedObject为例说明
	 */
	
	/**
	 * 演示如何对序列化数据进行签名加密
	 * @param args
	 */
	public static void main(String[] args) throws Throwable{
		SignedPerson signedPerson=new SignedPerson();
		signedPerson.setAge(18);
		signedPerson.setName("zheyuan");
		signedPerson.setNB(false);
		
		signedSerializableData(signedPerson);
	}
	
	static void signedSerializableData(Object signedPerson) throws Throwable{
		//-----------第一步:密钥武装序列化类--------------------
		
		//代做数字签名的原始信息(必须实现Serializable接口)
		Serializable o=(Serializable)signedPerson;
		//实例化KeyPairGenerator(密钥生成器)对象,并指定DSA算法
		KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("DSA");
		//初始化KeyPairGenerator对象
		int keysize=1024;
		keyPairGen.initialize(keysize);
		//生成KeyPair对象
		KeyPair keyPair=keyPairGen.generateKeyPair();
		//实例化Signature(用来生成和验证数字签名,是一个引擎类)对象
		Signature signature=Signature.getInstance(keyPairGen.getAlgorithm());
		//实例化SignedObject对象
		SignedObject sin=new SignedObject(o,keyPair.getPrivate(),signature);
		
		//----------第二步:将密钥武装后序列化类SignedObject序列化------------
		OutputStream out=new FileOutputStream("signed_temp");
		ObjectOutputStream oos=new ObjectOutputStream(out);
		oos.writeObject(sin);
		//-----------第三步:SignedObject反序列化-----------------------
		
		InputStream in=new FileInputStream("signed_temp");
		ObjectInputStream ois=new ObjectInputStream(in);
		SignedObject sout=(SignedObject)ois.readObject();
		
        //-------------第四步:将原始类信息解密-----------------		
		//获得签名值
		Object sign=sout.getObject();
		System.out.println(sign.toString());
		//验证签名
		boolean status=sout.verify(keyPair.getPublic(), signature);
		System.out.println(status);
		
	}

}


 

你可能感兴趣的:(java,算法,Security,项目管理)