Java:使用 DES 解密对象时发生 StreamCorruptedException [英] Java: StreamCorruptedException occur when Decrypt object with DES

查看:27
本文介绍了Java:使用 DES 解密对象时发生 StreamCorruptedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两种方法可以从 Android 内部存储的文件中加密保存和解密加载对象.

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

加密和保存过程没有任何问题,但是当我想加载对象时StreamCorruptedException发生在inputStream = new ObjectInputStream(cipherInputStream);

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.

我的代码如下:

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();
    }
}

加载方法:(不能从cipherInputStream加载对象)

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);

}

推荐答案

您至少犯了两个主要错误.

You're making at least two major mistakes.

  1. 您必须使用与加密时相同的密钥进行解密.你不能只生成一个随机密钥,除非它能够解密任何东西.密码学不是魔术.您必须安排以某种方式保存解密密钥,必要时传输,安全,并在解密步骤中使用.

  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.

您使用 SealedObject 加密一次,然后使用 CipherOutputStream 加密;然后在相反的方向,您使用 CipherInputStream 解密一次,然后通过 SealedObject 再次解密.这实际上是行不通的,因为 Cipher 对象在发送方和接收方的状态不同,而且在任何情况下都是毫无意义的.丢失 SealedObject 或 Cipher 流.

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.

这篇关于Java:使用 DES 解密对象时发生 StreamCorruptedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆