And*_*eaF 7 java encryption file-io android
我ArrayList
使用这两种方法在sd卡中保存并加载包含可序列化对象的文件
保存方法
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
加载方法
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我希望该方法saveUserList
根据特定String keyword
方法在保存期间加密文件的内容,并且该方法loadUserList
使用相同的关键字解密文件以返回arrayList.
我怎么能这样做?我已经看了一下,CipherOutputStream
但我还没明白应该如何使用它.
该方法建议使用Conceal库
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
导致此错误
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
Run Code Online (Sandbox Code Playgroud)
尝试(添加适当的检查并尝试我省略的块以使代码更具可读性)这样的东西来保存
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();
}
Run Code Online (Sandbox Code Playgroud)
这个加载
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;
}
Run Code Online (Sandbox Code Playgroud)
SecretKey
要从String 创建一个你可以使用它
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;
}
Run Code Online (Sandbox Code Playgroud)
注意:
此代码加密和解密两次,以显示密封对象和密码流的使用方式