序列化对象的ArrayList的加密后的保存和解密的负载负载、对象、序列化、ArrayList

2023-09-05 06:57:28 作者:承诺早已泛黄

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

}
 
谈一谈分布式架构的相关重要概念 RPC 高并发高可用 限流 熔断 负载均衡

导致此错误

 此错误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;
            sea​​ledObject =新的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;
        sea​​ledObject =(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;
    }