问题描述
我有两种方法可以从 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.
您必须使用与加密时相同的密钥进行解密.你不能只生成一个随机密钥,除非它能够解密任何东西.密码学不是魔术.您必须安排以某种方式保存解密密钥,必要时传输,安全,并在解密步骤中使用.
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!