Tuesday, April 20, 2010

combining PBE and XMLEncoder to generate encrypted file.

I have seen that many companies still be comfortable with putting their sensitive information in a plain text configuration file. Now, I use PHP and Zend Framework to develop enterprise application. I saw popular function MD5 and SHA is widely used by PHP programmer to protect sensitive data. It is not enough to protect data like password as message digest is not encryption algorithm. It is used to ensure data integrity.

I find back the configuration file encryption Java code. It is pretty easy to implement Passphase Based Encryption (PBE) in Java. I like to use XMLEncoder and XMLDecoder to write and read configuration file as it make simple code and good OO manner. However, XMLEncoder write Java object in a plain xml file. So, I create my own simple EncryptXMLEncoder and DecryptXMLDecoder to wrap around XMLEncoder and XMLDecoder. With EncryptXMLEncoder and DecryptXMLDecoder, I can write Java object into an encrypted file and read it back to a Java object.

These classes has potential to be expanded to be part of license manager. I will put my license manager design later. Also, I will implemented similar class in PHP later.

DummyDemo.java
package jia.blog.util.cfg;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import jia.blog.util.beans.DecryptedXMLDecoder;
import jia.blog.util.beans.EncryptedXMLEncoder;

/**
 *
 * @author Yiyu Jia
 */
public class DummyDemo {


    static public void main(String argv[]) {
        
        try {
            //I use a simple DB configuration object for demo.
            DBConfiguration db = new DBConfiguration();
            db.setDbDriverName("com.mysql.jdbc.Driver");
            db.setDbURI("jdbc:mysql://localhost:3306/jiaBlog");
            db.setDbUser("yiyu.jia");
            db.setDbPassword("****");
            db.setDbPoolMinSize(1);
            db.setDbPoolMaxSize(5);

            //point out where the configuration file will be saved
            FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + File.separator + "cfg" + File.separator + "dbCfg.xml");
            BufferedOutputStream bos = new BufferedOutputStream(fos);

            //initialized an EcnryptedXMLEncoder with pass in passphase and salt string.
            EncryptedXMLEncoder xmlEncoder = new EncryptedXMLEncoder(bos, "a complex password is a passphase", "put some salt for better taste");
            //write the object to file. writing is down!
            xmlEncoder.writeObject(db);

            //point out where the configuration file will be read.
            FileInputStream fis = new FileInputStream(System.getProperty("user.dir") + File.separator + "cfg" + File.separator + "dbCfg.xml");

            //initialized an DecryptedXMLEncoder with pass in passphase string and salt string.
            DecryptedXMLDecoder xmlDecoder = new DecryptedXMLDecoder(fis, "a complex password is a passphase", "put some salt for better taste");
            DBConfiguration dbCfg = (DBConfiguration )xmlDecoder.readObject();

            //let's see whether we get back the configuration correctly. 
            System.out.print(dbCfg.getDbDriverName() + "\n"
                        + dbCfg.getDbUser() + "\n"
                        + dbCfg.getDbPassword());
            
        } catch (IOException ex) {
            Logger.getLogger(DummyDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(DummyDemo.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            
        }
    }
}


EncryptedXMLEncoder.java
package jia.blog.util.beans;

import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 *
 * @author Yiyu Jia
 */
public class EncryptedXMLEncoder {

    OutputStream out;
    String passphase, salt;

    public EncryptedXMLEncoder(OutputStream out, String passphase, String salt) {
        this.out = out;
        this.passphase = passphase;
        this.salt = salt;
    }

    public void writeObject(Object o) throws IOException, Exception {

        //I simply use ByteArrayOutputStream here.
        //We can swith to piped stream if the object is really large.
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XMLEncoder xmlEncoder = new XMLEncoder(baos);
        xmlEncoder.writeObject(o);
        xmlEncoder.close();        
        InputStream is =new ByteArrayInputStream(baos.toByteArray());
        baos.close();        
        Encrypter.encryptOutput(passphase, salt, is, out);

    }
}

DecryptedXMLDecoder.java
package jia.blog.util.beans;

import java.beans.XMLDecoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 *
 * @author Yiyu Jia
 */
public class DecryptedXMLDecoder {

    InputStream in;
    String passphase, salt;

    public DecryptedXMLDecoder(InputStream in, String passphase, String salt) {
        this.in = in;
        this.passphase = passphase;
        this.salt = salt;
    }

    public Object readObject() throws Exception {

        //I simply use ByteArrayOutputStream here.
        //We can swith to piped stream if the object is really large.
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Encrypter.decryptInput(passphase, salt, in, baos );
        InputStream is =new ByteArrayInputStream(baos.toByteArray());
        XMLDecoder xmlDecoder = new XMLDecoder(is);
        Object o = xmlDecoder.readObject();
        xmlDecoder.close();
        return o;
    }
}


click here for netbean project files.

No comments:

Post a Comment