(蚂蚁金服mPaaS)统一存储

栏目: Android · 发布时间: 6年前

内容简介:基于 OrmLite 架构,参考:在数据库创建或者打开的时候,传入passwordSQLite加密方式最终调SQLiteConnection.java
  1. 数据库存储 :基于 OrmLite 架构,提供了数据库底层加密能力。
  2. 键值对存储 :基于 Android 原生的 SharedPreferences,同时进行了一定的包装,提升了易用性。
  3. 文件存储 :基于 Android 原生 File,提供了文件加密能力。

二:存储方案

1. 数据库存储方案

(1) 架构

基于 OrmLite 架构,参考: 【Android - 框架】之ORMLite的使用

(2) 安全性

在数据库创建或者打开的时候,传入passwordSQLite加密方式

public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        this.mPassword = null;
        ...
    }


    public SQLiteDatabase getWritableDatabase() {
        synchronized(this) {
            return this.getDatabaseLocked(true);
        }
    }

    public SQLiteDatabase getReadableDatabase() {
        synchronized(this) {
            return this.getDatabaseLocked(false);
        }
    }
    
    private SQLiteDatabase getDatabaseLocked(boolean writable) {
        ...

                        db = SQLiteDatabase.openOrCreateDatabase(dbFile.getAbsolutePath(), this.mFactory, this.mErrorHandler, this.mEnableWriteAheadLogging, this.mPassword);
                    } catch (SQLiteException var14) {
                        if(writable) {
                            throw var14;
                        }
        ...
    }
复制代码

最终调SQLiteConnection.java

private void open() {
        this.mConnectionPtr = nativeOpen(this.mConfiguration.path, this.mConfiguration.openFlags, this.mConfiguration.label, false, false);
        this.setEncryptKey();
        this.setForeignKeyModeFromConfiguration();
        this.setWalModeFromConfiguration();
        this.setJournalSizeLimit();
        this.setAutoCheckpointInterval();
        this.setLocaleFromConfiguration();
        int functionCount = this.mConfiguration.customFunctions.size();

        for(int i = 0; i < functionCount; ++i) {
            SQLiteCustomFunction function = (SQLiteCustomFunction)this.mConfiguration.customFunctions.get(i);
            nativeRegisterCustomFunction(this.mConnectionPtr, function);
        }

    }
    
    private void setEncryptKey() {
        if(!this.mConfiguration.isInMemoryDb() && !this.mIsReadOnlyConnection) {
            String password = this.mConfiguration.password;
            if(password != null) {
                File encryptFile = new File(this.mConfiguration.path + "-encrypt");
                if(encryptFile.exists()) {
                    this.execute("PRAGMA key='" + password + "';", (Object[])null, (Object)null);
                } else {
                    this.execute("PRAGMA rekey='" + password + "';", (Object[])null, (Object)null);

                    try {
                        encryptFile.createNewFile();
                    } catch (IOException var4) {
                        Log.e("SQLiteConnection", "Can't touch " + encryptFile.getName() + ", can't rekey the database");
                    }
                }
            }
        }

    }
复制代码

(3) 使用便捷性

  • 不用写 sql 语句,创建数据库继承OrmLiteSqliteOpenHelper,建表通过JavaBean和注解的方式。增删改查使用Dao的方式。
  • 数据库加密,在创建时传入password即可。

2. 键值对存储方案

(1) 架构

封装类APSharedPreferences.java

private Context sContext = null;
    private String mGroup = "alipay_default_sp";  // 组id,与文件名类似
    private SharedPreferences mSP;
    private int mMode = 0;
    private Editor edit = null;

    public boolean getBoolean(String key, boolean defValue) {
        return this.getBoolean(this.getGroup(), key, defValue);
    }

    public String getString(String key, String defValue) {
        return this.getString(this.getGroup(), key, defValue);
    }
    ...
复制代码

管理类SharedPreferencesManager.java

private static LruCache<String, APSharedPreferences> spList = new LruCache(30); // 定义了一个最大长度为30的缓存列表,使用lru算法
    
    public SharedPreferencesManager() {
    }

    public static APSharedPreferences getInstance(Context context, String groupId) {
        return getInstance(context, groupId, 0);
    }

    public static APSharedPreferences getInstance(Context context, String groupId, int mode) {
        if(context != null && !TextUtils.isEmpty(groupId)) {
            APSharedPreferences sp = (APSharedPreferences)spList.get(groupId);
            if(sp == null) {
                Class var4 = SharedPreferencesManager.class;
                synchronized(SharedPreferencesManager.class) {
                    sp = (APSharedPreferences)spList.get(groupId);
                    if(sp == null) {
                        sp = new APSharedPreferences(context, groupId, mode);
                        spList.put(groupId, sp);
                    }
                }
            }

            return sp;
        } else {
            return null;
        }
    }
复制代码

(2) 加密

(3) 使用便捷性

  • 对SharedPreferences api做了封装,更方便使用
  • 对文件分组,便于管理,增加了增删改操作。
  • 使用LruCache,加快读写速度。

3. 文件存储方案

(1) 架构

  • ZFile:该文件类型存储在 data/data/package_name/files 下。
  • ZExternalFile:该文件类型存储在 sdcard/Android/data/package_name/files 下。
  • ZFileInputStream/ZFileOutputStream:文件存储输入输出流,使用该流则不进行加解密。
  • ZSecurityFileInputStream/ZSecurityFileOutputStream:文件存储安全输入输出流,使用该流则会

ZFile.java

public class ZFile extends BaseFile {
    private static final long serialVersionUID = -1952946196402763362L;
    // groupId为目录,name为文件名,subPath为相对子路径
    public ZFile(Context context, String groupId, String name, String subPath) {
        super(buildPath(context, groupId, name, subPath));
    }

    public ZFile(Context context, String groupId, String name) {
        super(buildPath(context, groupId, name, (String)null));
    }

    private static String buildPath(Context context, String groupId, String name, String subPath) {
                ...
                String path = "";
                // 拼文件路径
                String dir = context.getFilesDir() + File.separator + groupId + formatPath(subPath);
                File fileDir = new File(dir);
                if(!fileDir.exists()) {
                    fileDir.mkdirs();
                }
                path = dir + name;
                return path;
                ...
    }
}
复制代码

ZExternalFile.java

public class ZExternalFile extends BaseFile {
    private static final String Tag = "ZExternalFile";
    protected static final String ExtDataTunnel = "ExtDataTunnel";
    private static final long serialVersionUID = -3489082633723468737L;

    public ZExternalFile(Context context, String groupId, String name, String subPath) {
        super(buildPath(context, groupId, name, subPath));
    }

    public ZExternalFile(Context context, String groupId, String name) {
        super(buildPath(context, groupId, name, (String)null));
    }

    private static String buildPath(Context context, String groupId, String name, String subPath) {
            ...
            File externalFilesDir = null;

            try {
                externalFilesDir = context.getExternalFilesDir(groupId);
            } catch (Throwable var8) {
                Log.w("ZExternalFile", "context.getExternalFilesDir(" + groupId + ") failed!", var8);
            }

            String path;
            String dir;
            if(externalFilesDir == null) {
                Log.w("ZExternalFile", "externalFilesDir is null");
                path = FileUtils.getSDPath();
                if(TextUtils.isEmpty(path)) {
                    return "";
                }

                dir = path + File.separator + "ExtDataTunnel" + File.separator + "files" + File.separator + groupId;
                externalFilesDir = new File(dir);
            }

            path = "";
            dir = externalFilesDir.getAbsolutePath() + formatPath(subPath);
            File fileDir = new File(dir);
            if(!fileDir.isDirectory() || !fileDir.exists()) {
                fileDir.mkdirs();
            }

            path = dir + name;
            return path;
            ...
    }
}
复制代码

ZSecurityFileOutputStream.java

public class ZSecurityFileOutputStream extends ZFileOutputStream {
    
    public void write(byte[] buffer) throws IOException {
        this.byteList.add(buffer);
        this.byteSize += buffer.length;
    }
    
    public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException {
        int size = byteCount;
        if(byteCount > buffer.length) {
            size = buffer.length;
        }

        byte[] sBuffer = new byte[size];
        System.arraycopy(buffer, byteOffset, sBuffer, 0, size);
        this.byteList.add(sBuffer);
        this.byteSize += size;
    }
    
    // 在close的时候,才将数据加密并且写入文件
    public void close() throws IOException {
        byte[] finalByte = new byte[this.byteSize];
        int pos = 0;
        if(this.byteList != null && !this.byteList.isEmpty()) {
            for(int i = 0; i < this.byteList.size(); ++i) {
                byte[] item = (byte[])this.byteList.get(i);
                if(this.byteSize >= pos + item.length) {
                    System.arraycopy(item, 0, finalByte, pos, item.length);
                }

                pos += item.length;
            }

            this.byteList.clear();
            Object var6 = null;

            byte[] enByte;
            try {
                // 加密
                enByte = TaobaoSecurityEncryptor.encrypt(this.mContext, finalByte);
            } catch (Exception var5) {
                throw new IOException(var5);
            }

            super.write(enByte, 0, enByte.length);
            super.close();
        }
    }
}
复制代码

ZSecurityFileInputStream.java

private void initBuffer() throws IOException {
        int size = super.available();
        byte[] enBuffer = new byte[size];
        super.read(enBuffer, 0, enBuffer.length);
        super.close();

        try {
            // 解密
            this.mBuffer = TaobaoSecurityEncryptor.decrypt(this.mContext, enBuffer);
        } catch (Exception var4) {
            LoggerFactory.getTraceLogger().warn("ZSecurityFileInputStream", var4);
            throw new IOException();
        }
    }
复制代码

以上所述就是小编给大家介绍的《(蚂蚁金服mPaaS)统一存储》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Linux Command Line

The Linux Command Line

William E. Shotts Jr. / No Starch Press, Incorporated / 2012-1-17 / USD 39.95

You've experienced the shiny, point-and-click surface of your Linux computer-now dive below and explore its depths with the power of the command line. The Linux Command Line takes you from your very ......一起来看看 《The Linux Command Line》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试