Encrypted save and decrypted load of an ArrayList of serializable objects

前端 未结 3 1532
情书的邮戳
情书的邮戳 2021-02-04 17:37

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 sa         


        
相关标签:
3条回答
  • 2021-02-04 17:47

    You could simply use 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"));
    }
    

    Then, for trying it, this example may be valid for you:

    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);
    

    Of course, douncrypt must match This is a phrase to be encrypted!

    0 讨论(0)
  • 2021-02-04 18:00

    I suggest taking a look at Conceal, recently released by facebook: http://facebook.github.io/conceal/

    This should be a trivial modification to wrap a Conceal output stream with an ObjectOutputStream used in your current code:

    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();
            }
        }
    
    }
    

    I'll leave the restore as an exercise for the reader. ;)

    0 讨论(0)
  • 2021-02-04 18:02

    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;
        }
    

    NOTE:

    this code encrypts and decrypts twice to show the way of use of both sealed object and Cipher streams

    0 讨论(0)
提交回复
热议问题