ValidatingObjectInputStream引发EOF异常

时间:2018-10-26 14:09:35

标签: java serialization deserialization

我正在尝试通过使用Apache API ValidatingObjectInputStream建立针对Java反序列化漏洞的防御。

但是由于以下异常而失败,并且不确定此处可能缺少什么:

Object has been serialized
IOException is caught
java.io.StreamCorruptedException: invalid stream header: 74000732
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:863)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:355)
    at org.apache.commons.io.serialization.ValidatingObjectInputStream.<init>(ValidatingObjectInputStream.java:59)
    at com.apple.ctbdp.controller.Test.deSerialize(Test.java:44)
    at com.apple.ctbdp.controller.Test.main(Test.java:28)

Test.java

class Test {
    public static void main(String[] args) {

        String object = new String("2323232");


        String filename = "file.ser";

        serialize(object, filename);

        deSerialize(filename);

    }

    private static void deSerialize(String filename) {
        String object1 = null;


        try {
            // Reading the object from a file
            FileInputStream fis = new FileInputStream(filename);

            ObjectInputStream in = new ObjectInputStream(fis);

            final ValidatingObjectInputStream objectInStream = new ValidatingObjectInputStream(fis);
            objectInStream.accept(String.class);


            // Method for deserialization of object
            object1 = (String) objectInStream.readObject();



            in.close();
            fis.close();

            System.out.println("Object has been deserialized ");
            System.out.println("Test.deSerialize() " + object1);
        }

        catch (IOException ex) {
            ex.printStackTrace();
            System.out.println("IOException is caught");
        }

        catch (ClassNotFoundException ex) {
            System.out.println("ClassNotFoundException is caught");
        }
    }

    private static void serialize(String object, String filename) {
        // Serialization
        try {
            // Saving of object in a file
            FileOutputStream file = new FileOutputStream(filename);
            ObjectOutputStream out = new ObjectOutputStream(file);

            // Method for serialization of object
            out.writeObject(object);

            out.close();
            file.close();

            System.out.println("Object has been serialized");

        }

        catch (IOException ex) {
            System.out.println("IOException is caught");
        }
    }
}

在这方面感谢您的提示/建议。

1 个答案:

答案 0 :(得分:0)

我没有关闭ValidatingObjectInputStream对象,而是关闭了ObjectInputStream对象。进行此更改后,它现在可以正常工作。

更新的代码:

static string testFunc()
    {
        byte[] IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        byte[] key = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

        //presumably this should need padding by 6 bytes
        byte[] data = Encoding.ASCII.GetBytes("1234567890");
        byte[] padded = new byte[16];

        Array.Copy(data, 0, padded, 0, data.Length);
        for (int a = data.Length; a < padded.Length; a++)
        {
            padded[a] = 7;
        }

        byte[] encrypted = CbcEncrypt(padded, key, IV);

        string base64 = Convert.ToBase64String(CbcDecrypt(encrypted, key, IV));
        Console.WriteLine(Encoding.UTF8.GetString(Convert.FromBase64String(base64)));
        return "";
    }

    public static byte[] CbcEncrypt(byte[] data, byte[] key, byte[] IVector)
    {
        var a = new AesManaged();
        a.Key = key;
        a.IV = IVector;
        a.Mode = CipherMode.CBC;

        var encryptor = a.CreateEncryptor();

        byte[] result = encryptor.TransformFinalBlock(data, 0, data.Length);
        return result;
    }


    public static byte[] CbcDecrypt(byte[] data, byte[] key, byte[] IVector)
    {
        var a = new AesManaged();
        a.Key = key;
        a.IV = IVector;
        a.Mode = CipherMode.CBC;

        var decryptor = a.CreateDecryptor();

        byte[] result = decryptor.TransformFinalBlock(data, 0, data.Length);
        return result;