我在SD卡保存和加载一个包含 ArrayList的一个文件,这两种方法序列化对象的
保存方法
公共静态无效saveUserList(ArrayList的<使用者>用户列表){
如果(storageAvailable()){
尝试 {
创建文件夹();
FileOutputStream中用户列表=新的FileOutputStream(
BASEDIR +文件分割符+ baseAppDir +文件分割符
+文件名);
ObjectOutputStream的OOS =新的ObjectOutputStream(
用户列表);
oos.writeObject(用户列表);
oos.close();
}赶上(例外EXC){
exc.printStackTrace();
}
}
}
加载方法
公共静态的ArrayList<使用者> loadUserList(){
如果(storageAvailable()){
ArrayList的<使用者>用户列表=新的ArrayList<使用者>();
尝试 {
的FileInputStream用户列表=新的FileInputStream(BASEDIR
+文件分割符+ baseAppDir +文件分割符
+文件名);
ObjectInputStream的OOS =新的ObjectInputStream(
用户列表);
用户列表=(ArrayList的<使用者>)oos.readObject();
oos.close();
}赶上(例外EXC){
exc.printStackTrace();
}
返回用户列表;
} 其他 {
返回null;
}
}
现在我想,该方法 saveUserList
加密文件的过程中的含量根据特定的保存字符串关键字
该方法 loadUserList
解密用相同的关键字返回数组列表文件。
我怎么能这样做?
我给一看 CipherOutputStream
,但我不明白我应该怎么用这个。
提出的方法使用隐藏式库
公共静态无效saveUserListCrypted(ArrayList的<使用者>用户列表){
如果(storageAvailable()){
尝试 {
创建文件夹();
加密密码=新的密码(
新的共享prefsBackedKeyChain(上下文),
新SystemNativeCryptoLibrary());
FileOutputStream中用户列表=新的FileOutputStream(
BASEDIR +文件分割符+ baseAppDir +文件分割符
+文件名);
OutputStream的cryptedStream = crypto.getCipherOutputStream(
用户列表,新的实体(在UserList);
ObjectOutputStream的OOS =新的ObjectOutputStream(
cryptedStream);
oos.writeObject(用户列表);
oos.close();
}赶上(例外EXC){
exc.printStackTrace();
}
}
}
导致此错误
此错误java.lang.UnsupportedOperationException 02-12 21:29:05.026 2051年至2051年/ com.myapp W / System.err的:在com.facebook.crypto.streams.NativeGCMCipherOutputStream 。写
解决方案
尝试(加入适当的检查和试块,我省略使code更具可读性)这样的东西保存
公共静态无效AESObjectEn codeR(Serializable对象,字符串密码,字符串路径){
尝试 {
密码加密= NULL;
密码= Cipher.getInstance(AES / CBC / PKCS7Padding);
cipher.init(Cipher.ENCRYPT_MODE,fromStringToAESkey(密码));
SealedObject sealedObject = NULL;
sealedObject =新的SealedObject(对象,密码);
CipherOutputStream cipherOutputStream = NULL;
cipherOutputStream =新CipherOutputStream(新的BufferedOutputStream(新的FileOutputStream(路径)),密码);
ObjectOutputStream中的OutputStream = NULL;
的OutputStream =新的ObjectOutputStream(cipherOutputStream);
outputStream.writeObject(sealedObject);
outputStream.close();
}
和此加载
公共静态序列化AESObjectDed codeR(字符串密码,字符串路径){
密码加密= NULL;
序列化的用户列表= NULL;
密码= Cipher.getInstance(AES / CBC / PKCS7Pdding);
// code来写你的对象文件
cipher.init(Cipher.DECRYPT_MODE,fromStringToAESkey(密码));
CipherInputStream cipherInputStream = NULL;
cipherInputStream =新CipherInputStream(新的BufferedInputStream(新的FileInputStream(路径)),密码);
ObjectInputStream中的InputStream = NULL;
的InputStream =新的ObjectInputStream(cipherInputStream);
SealedObject sealedObject = NULL;
sealedObject =(SealedObject)inputStream.readObject();
用户列表=(序列化)sealedObject.getObject(萃丰时代);
返回用户列表;
}
创建一个 SecretKey的
从一个字符串,你可以使用这个
公共静态SecretKey的fromStringToAESkey(String s)将{
// 256bit的密钥需要32字节
byte []的rawKey =新的字节[32];
//如果不指定编码,你可能会得到怪异的结果
byte []的keyBytes =新的字节[0];
尝试 {
keyBytes = s.getBytes(ASCII);
}赶上(UnsupportedEncodingException E){
e.printStackTrace();
}
System.arraycopy(keyBytes,0,rawKey,0,keyBytes.length);
SecretKey的关键=新SecretKeySpec(rawKey,AES);
返回键;
}
I save and load in sd card a file that contains an ArrayList
of serializable object with these two methods
save method
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();
}
}
}
load method
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;
}
}
Now I want that the method saveUserList
encrypts the content of the file during the save according a specific String keyword
and the method loadUserList
decrypts the file with the same keyword to return the arrayList.
How could I do this?
I have given a look to CipherOutputStream
but I haven't understood how should I use this.
The method proposed to use Conceal library
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();
}
}
}
cause this error
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
解决方案
Try (adding the appropriate checks and try blocks that I have omitted to make the code more readable) something like this to save
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();
}
and this to load
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;
}
to create a SecretKey
from a String you can use this
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;
}