我ArrayList使用以下两种方法将包含可序列化对象的文件保存并加载到SD卡中
ArrayList
保存方法
public static void saveUserList(ArrayList<User> userList) { if (storageAvailable()) { try { createFolder(); FileOutputStream userList = new FileOutputStream( baseDir + File.separator + baseAppDir + File.separator + fileName); ObjectOutputStream oos = new ObjectOutputStream( userList); oos.writeObject(userList); oos.close(); } catch (Exception exc) { exc.printStackTrace(); } } }
加载方式
public static ArrayList<User> loadUserList() { if (storageAvailable()) { ArrayList<User> userList = new ArrayList<User>(); try { FileInputStream userList = new FileInputStream(baseDir + File.separator + baseAppDir + File.separator + fileName); ObjectInputStream oos = new ObjectInputStream( userList); userList = (ArrayList<User>) oos.readObject(); oos.close(); } catch (Exception exc) { exc.printStackTrace(); } return userList; } else { return null; } }
现在,我希望该方法saveUserList根据特定的内容在保存期间加密文件的内容,String keyword并且该方法loadUserList使用相同的关键字解密文件以返回arrayList。
saveUserList
String keyword
loadUserList
我该怎么办?我看了一下,CipherOutputStream但我不知道该怎么用。
CipherOutputStream
建议使用隐蔽库的方法
public static void saveUserListCrypted(ArrayList<User> userList) { if (storageAvailable()) { try { createFolder(); Crypto crypto = new Crypto( new SharedPrefsBackedKeyChain(context), new SystemNativeCryptoLibrary()); FileOutputStream userList = new FileOutputStream( baseDir + File.separator + baseAppDir + File.separator + fileName); OutputStream cryptedStream = crypto.getCipherOutputStream( userList, new Entity("UserList"); ObjectOutputStream oos = new ObjectOutputStream( cryptedStream); oos.writeObject(userList); oos.close(); } catch (Exception exc) { exc.printStackTrace(); } } }
导致这个错误
this error java.lang.UnsupportedOperationException 02-12 21:29:05.026 2051-2051/com.myapp W/System.err﹕ at com.facebook.crypto.streams.NativeGCMCipherOutputStream.write
请尝试(添加适当的检查并尝试省略的块以使代码更具可读性)这样的保存
public static void AESObjectEncoder(Serializable object, String password, String path) { try { Cipher cipher = null; cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); cipher.init(Cipher.ENCRYPT_MODE, fromStringToAESkey(password)); SealedObject sealedObject = null; sealedObject = new SealedObject(object, cipher); CipherOutputStream cipherOutputStream = null; cipherOutputStream = new CipherOutputStream(new BufferedOutputStream(new FileOutputStream(path)), cipher); ObjectOutputStream outputStream = null; outputStream = new ObjectOutputStream(cipherOutputStream); outputStream.writeObject(sealedObject); outputStream.close(); }
这要加载
public static Serializable AESObjectDedcoder(String password, String path) { Cipher cipher = null; Serializable userList = null; cipher = Cipher.getInstance("AES/CBC/PKCS7Pdding"); //Code to write your object to file cipher.init(Cipher.DECRYPT_MODE, fromStringToAESkey(password)); CipherInputStream cipherInputStream = null; cipherInputStream = new CipherInputStream(new BufferedInputStream(new FileInputStream(path)), cipher); ObjectInputStream inputStream = null; inputStream = new ObjectInputStream(cipherInputStream); SealedObject sealedObject = null; sealedObject = (SealedObject) inputStream.readObject(); userList = (Serializable) sealedObject.getObject(ciper); return userList; }
SecretKey从字符串创建一个,您可以使用此
SecretKey
public static SecretKey fromStringToAESkey(String s) { //256bit key need 32 byte byte[] rawKey = new byte[32]; // if you don't specify the encoding you might get weird results byte[] keyBytes = new byte[0]; try { keyBytes = s.getBytes("ASCII"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.arraycopy(keyBytes, 0, rawKey, 0, keyBytes.length); SecretKey key = new SecretKeySpec(rawKey, "AES"); return key; }
注意:
此代码两次加密和解密,以显示密封对象和密码流的使用方式