加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Java序列化的高级认识-对敏感字段加密

(2014-03-13 18:13:45)
标签:

it

分类: Java
  情境:服务端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。
  解决:在序列化过程中,虚拟机会试图调用对象类里的writeObject和readObject方法,进行用户自定义的序列化和反序列化,如果没有这样的方法,则会默会调用ObjectOutputStream的defaultWriteObject方法以及ObjectInputStream的defaultReadObject方法。用户自定义的writeObject和readObject方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。基于这个原理,可以在实际应用中得到使用,用于敏感字段的加密工作。
package JavaSerializable;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream.PutField;

public class EncryptTest implements Serializable {

   
    private static final long serialVersionUID = 1L;
    private String password = "password1";

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

     private void writeObject(ObjectOutputStream out) { 
            try { 
                PutField putFields = out.putFields(); 
                System.out.println("原密码:" + password); 
                password = password+"GL";// 模拟加密  
                putFields.put("password", password); 
                System.out.println("加密后的密码字符串" + password); 
                out.writeFields(); 
            } catch (IOException e) { 
                e.printStackTrace(); 
           
       


    private void readObject(ObjectInputStream in) { 
        try { 
            GetField readFields = in.readFields(); 
            Object object = readFields.get("password", ""); 
            System.out.println("读取解密的密码字符串:" + object.toString()); 
        //    password = "password1";// 模拟解密,需要获得本地的密钥  
            //获取指定规则的真密码object.toString().length()-2,因为前面加的GL
            setPassword(object.toString().substring(0,object.toString().length()-2));
        } catch (IOException e) { 
            e.printStackTrace(); 
        } catch (ClassNotFoundException e) { 
            e.printStackTrace(); 
       
    }
    public static void main(String[] args){
        try {
            ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("result.obj"));
            out.writeObject(new EncryptTest());
            out.close();
            ObjectInputStream oin=new ObjectInputStream(new FileInputStream("result.obj"));
            EncryptTest t=(EncryptTest)oin.readObject();
           
            System.out.println("真正的密码字符串:"+t.getPassword());
            oin.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
    }
}
  RMI技术是完全基于Java序列化技术的,服务器端接口调用所需要的参数对象来自客户端,它们通过网络相互传输。这就涉及RMI的安全传输的问题。一般敏感的字段,如用户名密码(用户登录时需要对密码进行传输),我们希望对其进行加密,这时,就可以采用本节介绍的方法在客户端对密码进行加密,服务器进行解密,确保数据传输的安全性。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有