Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
218 views
in Technique[技术] by (71.8m points)

android - Java: StreamCorruptedException occur when Decrypt object with DES

I have two method for Encrypt-save and decrypt-load Object from file in Android Internal Storage.

Encrypt and save process is done without any problem, but when I want to load the object StreamCorruptedException occurs in inputStream = new ObjectInputStream(cipherInputStream);

I searched SO more and more but I did't find a solution for my problem. all other solutions are for socket life or like this.

my code is below:

private static byte[] iv = { (byte) 0xB1, (byte) 0x15, (byte) 0xB5,
        (byte) 0xB7, (byte) 0x66, (byte) 0x43, (byte) 0x2F, (byte) 0xA4,
        (byte) 0xB1, (byte) 0x15, (byte) 0x35, (byte) 0xC7, (byte) 0x66,
        (byte) 0x58, (byte) 0x2F, (byte) 0x5F };

save method: (work well)

private static String saveToFile(Serializable object, String fileName,
        Context ctx) {
    try {
        Cipher cipher = null;
        cipher = Cipher.getInstance("DES");
        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
        AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        SealedObject sealedObject = null;
        sealedObject = new SealedObject(object, cipher);
        CipherOutputStream cipherOutputStream = null;

        FileOutputStream fos = ctx.openFileOutput(fileName,
                Context.MODE_PRIVATE);
        cipherOutputStream = new CipherOutputStream(
                new BufferedOutputStream(fos), cipher);
        ObjectOutputStream outputStream = null;
        outputStream = new ObjectOutputStream(cipherOutputStream);
        outputStream.writeObject(sealedObject);
        outputStream.close();

        return "Save Complete!";

    } catch (IOException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
        return e.getMessage();
    }
}

Load method: (can't load object from cipherInputStream)

private static Serializable loadFromFile(String fileName, Context ctx) {
    Cipher cipher = null;
    Serializable userList = null;
    try {
        cipher = Cipher.getInstance("DES");

        // Code to write your object to file
        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
        AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);

        cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
        CipherInputStream cipherInputStream = null;

        FileInputStream fos = ctx.openFileInput(fileName);
        cipherInputStream = new CipherInputStream(new BufferedInputStream(
                fos), cipher);

        ObjectInputStream inputStream = null;
        inputStream = new ObjectInputStream(cipherInputStream);
        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        SealedObject sealedObject = null;
        sealedObject = (SealedObject) inputStream.readObject();
        userList = (Serializable) sealedObject.getObject(cipher);
        inputStream.close();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (StreamCorruptedException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (IOException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
        return e.getMessage();
    } catch (BadPaddingException e) {
        e.printStackTrace();
        return e.getMessage();
    }
    return userList;
}

public methods for save and load:

public Serializable loadPlayer(Context ctx) {
    return loadFromFile("player.dat", ctx);
}

public String savePlayer(Player player, Context ctx) {
    return saveToFile(player, "player.dat", ctx);

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're making at least two major mistakes.

  1. You have to use the same key to decrypt as you used to encrypt. You can't just generate a random key and except it to be able to decrypt anything. Cryptology isn't magic. You will have to arrange for the decryption key to be preserved somehow, transmitted if necessary, securely, and used at the decryption step.

  2. You're encrypting once with the SealedObject and again with the CipherOutputStream; then in the reverse direction you're decrypting once with the CipherInputStream and again via the SealedObject. This won't actually work, because the Cipher object isn't in comparable states at sender and receiver, and in any case it's pointless. Lose either the SealedObject or the Cipher streams.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...