Ad

Thursday, 4 September 2014

To secure and protect the sensitive information in serializable object

By using serialization we can save the  object state to the stream and we can  construct the saved object back from the stream when needed.Sometime we need to secure some attributes in our object to not to  get serialized i.e not to save its value.Consider the below code example where we are writing the StudentVo object to the file and reading back from it.

StudentVO.Java

import java.io.Serializable;                                                                                                                    

public class StudentVO implements Serializable {

private String loginId;

private  String password;

private String fullName;

private int age;

public StudentVO(String loginId, String password, String fullName,
int age) {
super();
this.loginId = loginId;
this.password = password;
this.fullName = fullName;
this.age = age;
}

@Override
public String toString() {
return "StudentVO [loginId=" + loginId + ", password=" + password
+ ", fullName=" + fullName + ", age=" + age + "]";
}
}

SerializerSample.java

import java.io.FileInputStream;                                                                                                              
import java.io.FileOutputStream;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializerSample {

private final static String  FILE_NAME="D:/objfile";

public static void main(String[] args) {
      StudentVO studentVO = new StudentVO("V01", "pwd", "John Peter", 20);
      SerializerSample serializerSample= new SerializerSample();
      serializerSample.serialize(studentVO);
      studentVO=serializerSample.deSerialize();
      System.out.println("Object deserialized from file is:"+studentVO.toString());
}

private void serialize(StudentVO  studentVO)
{
try {
    FileOutputStream fileOutputStream= new FileOutputStream(FILE_NAME);
      ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(studentVO);
   fileOutputStream.close();
   objectOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}

private StudentVO deSerialize()
{
StudentVO studentVO=null;
try
{
FileInputStream fileInputStream= new FileInputStream(FILE_NAME);
ObjectInputStream objectInputStream= new ObjectInputStream(fileInputStream);
studentVO=(StudentVO) objectInputStream.readObject();
   fileInputStream.close();
   objectInputStream.close();
}catch (Exception e) {
e.printStackTrace();
}
return studentVO;
}
}

As we can see in the Class SerializerSample,first we will  write the object state to the file(in method serialize()) and then construct the object back from the file(in method deSerialize()).
When we run the program,we will get the below output:

Object deserialized from file is:StudentVO [loginId=V01, password=pwd, fullName=John Peter, age=20]

Since the password is an sensitive attribute,we should not save its value when serilaized into the file.
There are three ways to secure a serializable object
  1. Declaring the sensitive field as transient
  2. Declaring the field serialPersistentFields
  3. Defining writeObject and readObject methods
1)Declaring the sensitive field as transient

values for the attributes which are declared as transient will not be saved when the object is serialized.So declare the field password as transient in StudentVO as shown below,so that its state will not be saved.

private transient String password;                                                                                                              

2)Declaring the field serialPersistentFields

we can define the serializable fields that need to be saved using the attribute serialPersistentFields in the serializable class.This field should be initialized with an array of ObjectStreamField as shown below.

import java.io.ObjectStreamField;                                                                                                            
import java.io.Serializable;

public class StudentVO implements Serializable {
private String loginId;
private  String password;
private String fullName;
private int age;

private static final ObjectStreamField[] serialPersistentFields
 = {new ObjectStreamField("loginId", String.class),
      new ObjectStreamField("fullName", String.class),
      new ObjectStreamField("age",Integer.TYPE)};

public StudentVO(String loginId, String password, String fullName,
int age) {
super();
this.loginId = loginId;
this.password = password;
this.fullName = fullName;
this.age = age;
}

@Override
public String toString() {
return "StudentVO [loginId=" + loginId + ", password=" + password
+ ", fullName=" + fullName + ", age=" + age + "]";
}
}


We have defined only the fields loginid,fullName and age in the serialPersistentFields so that only this fields will be saved to the file on serialization and not the password field.

3)Defining writeObject and readObject methods in the Serializable Class

We can define the methods writeObject and readObject in the serializable class to control what information to be saved and to be retrieved back from the stream.

import java.io.IOException;                                                                                                                      
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class StudentVO implements Serializable {
private String loginId;
private  String password;
private String fullName;
private int age;
 public StudentVO(String loginId, String password, String fullName,
int age) {
super();
this.loginId = loginId;
this.password = password;
this.fullName = fullName;
this.age = age;
}

 private void readObject(ObjectInputStream ois) throws IOException,                                          
 ClassNotFoundException {
loginId=(String) ois.readObject();
fullName=(String) ois.readObject();
age=ois.readInt();
}
 private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.writeObject(loginId);
    oos.writeObject(fullName);
    oos.writeInt(age);
 }

@Override
public String toString() {
return "StudentVO [loginId=" + loginId + ", password=" + password
+ ", fullName=" + fullName + ", age=" + age + "]";
}
}

When the StudentVo object is serialized using writeObject method of the objectOutputStream,it will delegate the call to the method writeObject in serializable class StudentVO class.Thus only the fields loginId,fullName and age will be saved and not the password field.

OUTPUT:

When we run the SerializerSample class by using any of the above 3 versions of the StudentVO,we will get the below output

Object deserialized from file is:StudentVO [loginId=V01, password=null, fullName=John Peter, age=20]

As we can see in the output, the password field value was not saved during serialization.

No comments:

Post a Comment