Search code examples
javaserializationapache-commonsbouncycastlex509

Java serialization (of an X509CertificateObject)


I'm trying to serialize and de-serialize a Bouncy Castle X509CertificateObject using org.apache.commons.lang3.SerializationUtils. Apparently the de-serialized object is of a different type (sun.security.x509.X509CertImpl) than the originally serialized object (org.bouncycastle.jce.provider.X509CertificateObject). Consequently casting fails. What am I doing wrong?

public static void test(X509CertificateObject certObj) {
    byte[] serializedObj;
    Object deSerializedObj;
    X509CertificateObject deSerializedCertObj;
    X509Certificate deSerializedCert;

    System.out.println("certObj type: " + certObj.getClass().getName());
    serializedObj = SerializationUtils.serialize(certObj);
    deSerializedObj = SerializationUtils.deserialize(serializedObj);
    System.out.println("deSerializedObj type: " + deSerializedObj.getClass().getName());
    deSerializedCert = (X509Certificate) deSerializedObj;
    System.out.println("deSerializedCert type: " + deSerializedCert.getClass().getName());
    deSerializedCertObj = (X509CertificateObject) deSerializedObj;
    System.out.println("deSerializedCertObj type: " + deSerializedCertObj.getClass().getName());
}

results in:

certObj type: org.bouncycastle.jce.provider.X509CertificateObject
deSerializedObj type: sun.security.x509.X509CertImpl
deSerializedCert type: sun.security.x509.X509CertImpl

and finally in

java.lang.ClassCastException: sun.security.x509.X509CertImpl cannot be cast to org.bouncycastle.jce.provider.X509CertificateObject
at Test.test(Test.java:1010)
at Test.main(Test.java:153)

Is this because the upper class of X509CertificateObject, which is X509Certificate, is abstract and/or because X509CertificateObject does not define its own serialVersionUID?


Solution

  • I finally found a workaround/solution. The Java serialization problem seems to be due to a conflict between BC and Java JCE. I'm now using XStream in connection with Apache Commons Codec:

    import org.apache.commons.codec.binary.StringUtils;
    import com.thoughtworks.xstream.XStream;
    
    public static byte[] serializeToXML(Object obj, XStream xStreamConfig)
        throws Exception
    {
        XStream xstream;
        String certObjString;
        byte[] certObjByte;
    
        if(xStreamConfig == null) {
            xstream = new XStream();
        } else {
            xstream = xStreamConfig;
        }
    
        certObjString = xstream.toXML(obj);
    
        certObjByte = StringUtils.getBytesUtf8(certObjString);
    
        return certObjByte;
    }
    
    public static Object deserializeFromXML(byte[] objectByteArray, XStream xStreamConfig)
    {
        String objectString;
        Object object;
        XStream xstream;
    
        if(xStreamConfig == null) {
            xstream = new XStream();
        } else {
            xstream = xStreamConfig;
        }
    
        objectString = StringUtils.newStringUtf8(objectByteArray);
    
        object = xstream.fromXML(objectString);
    
        return object;
    }