Grabación cifrada y carga descifrada de un ArrayList de objetos serializables
Ahorro y carga en la tarjeta del SD un archivo que contiene un ArrayList
del objeto serializable con estos dos métodos
Guardar método
- ¿Cómo puedo resolver el brut.androlib.AndrolibException
- Android Cambia el texto de TextView de otra clase
- Serialización y des-serialización de android.graphics.Bitmap en Java
- Picasso sigue recargando imágenes mientras se desplaza hacia arriba en listview, carga lentamente
- BufferedReader mientras lee datos Json
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(); } } }
Método de carga
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; } }
Ahora quiero que el método saveUserList
el contenido del archivo durante la saveUserList
acuerdo a una String keyword
específica y el método loadUserList
descifra el archivo con la misma palabra clave para devolver el arrayList.
¿Cómo podría hacer esto? He dado un vistazo a CipherOutputStream
pero no he entendido cómo debo usar esto.
El método propuesto para utilizar la biblioteca 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(); } } }
Causar este 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
- Vista de reciclador - cambia el tamaño de la vista de elemento mientras se desplaza (para efecto de carrusel)
- Firebase getDownloadURL
- Precargar la vista Web en la actividad A y pasarla a la actividad B para una carga más rápida
- Hacer referencia a una instancia de inclusión desde una clase interna
- Explicación necesaria en los métodos booleanos return
- Android, hacer desbordamiento de vista desplazable a la izquierda en lugar de a la derecha?
- Acceso a campos privados de paquetes en Java
- ¿Cómo implementar Google Maps dentro de un fragmento y usar el objeto GoogleMap?
Intenta (añadiendo las comprobaciones adecuadas y prueba los bloques que he omitido para que el código sea más legible) algo así para guardar
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(); }
Y esto para cargar
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; }
Para crear un SecretKey
partir de una String puedes usar esto
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; }
Sugiero echar un vistazo a Ocultar, recientemente publicado por facebook: http://facebook.github.io/conceal/
Esto debería ser una modificación trivial para envolver un flujo de salida Conceal con un ObjectOutputStream utilizado en su código actual:
public static void saveUserList(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(); } } }
Voy a dejar la restauración como un ejercicio para el lector. 😉
Simplemente puede usar AES Encoding:
private static byte[] getEncrypt(final String key, final String message) throws GeneralSecurityException { final byte[] rawData = key.getBytes(Charset.forName("US-ASCII")); if (rawData.length != 16) { // If this is not 16 in length, there's a problem with the key size, nothing to do here throw new IllegalArgumentException("You've provided an invalid key size"); } final SecretKeySpec seckeySpec = new SecretKeySpec(rawData, "AES"); final Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding"); ciph.init(Cipher.ENCRYPT_MODE, seckeySpec, new IvParameterSpec(new byte[16])); return ciph.doFinal(message.getBytes(Charset.forName("US-ASCII"))); } private static String getDecrypt(String key, byte[] encrypted) throws GeneralSecurityException { final byte[] rawData = key.getBytes(Charset.forName("US-ASCII")); if (rawData.length != 16) { // If this is not 16 in length, there's a problem with the key size, nothing to do here throw new IllegalArgumentException("Invalid key size."); } final SecretKeySpec seckeySpec = new SecretKeySpec(rawData, "AES"); final Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding"); ciph.init(Cipher.DECRYPT_MODE, seckeySpec, new IvParameterSpec(new byte[16])); final byte[] decryptedmess = ciph.doFinal(encrypted); return new String(decryptedmess, Charset.forName("US-ASCII")); }
Entonces, para probarlo, este ejemplo puede ser válido para usted:
final String encrypt = "My16inLengthKey5"; final byte[] docrypt = getEncrypt(encrypt, "This is a phrase to be encrypted!"); final String douncrypt = getDecrypt(encrypt.toString(), docrypt); Log.d("Decryption", "Decrypted phrase: " + douncrypt);
Por supuesto, douncrypt
debe coincidir This is a phrase to be encrypted!
- Android – obtener la selección de texto de EditText
- AlertDialog MultiChoiceItems Problemas de escucha