基于SQLCipher插件的Ionic SQLite数据库加密

一、思路历程:

因为之前据说 SQLCipher 插件不能很好地实现加解密的功能,而且之后还要与语音模块的C库做接口,所以本想就此做一个 Cordova 插件来做一层统一的C接口封装,来统一调用其它C接口,以便轻松扩展后面的C库,调研后发现代价较高。这个 Cordova-Hello-JNI-Plugin 可能以后要是做的时候还可能会用到。

  1. 插件至少要做 AndroidiOS 两套,Android 还好说,因为贫穷,iOS 没法测试。
  2. 还要写什么回调函数,烦得很

所以,思忖了再三,决定还是先搭环境看看 SQLCipher 加密到底哪里不好使。

二、 Ionic & Cordova环境搭建

据一开始那次搭 Ionic 的环境已过去半年,早已记不得,重新来吧。

  1. 新建Ionic工程
    ionic start sqlite-test2 blank
  2. 添加 CordovaAndroid 平台支持
    ionic cordova platform add android
  3. 添加 CordovaCrosswalk 支持
    cordova plugin add cordova-plugin-crosswalk-webview
  4. 添加 Cordovacordova-sqlcipher-adapter 插件支持
    cordova plugin add cordova-sqlcipher-adapter

好的,环境搭完了,值得一提的是,在第一次安装的时候会遇到一个报错,原因是 cordova-android 必须得是6版本。第二次,就没了🤭。

三、具体SQLite操作页面

  1. 添加页面
    ionic generate page sqlite

  2. Oh...不需要,我们在首页上做就可以,以上是想记录 generate 语句可以实现 Generate pipes, components, pages, directives, providers, and tabs (ionic-angular >= 3.0.0) (来自这里)的正规生成。以下为具体页面内容。
    home.html

    <ion-header>
      <ion-navbar>
        <ion-title>
          Ionic Blank
        </ion-title>
      </ion-navbar>
    </ion-header>
    
    <ion-content padding>
      <button ion-button (click)="openDB()">Open DB</button>
      <ion-label color="primary">SQL:</ion-label>
      <ion-input #sql_stm placeholder="SQL Statement"></ion-input>
      <button ion-button color="secondary" clear (click)="sql_stm.value=''">clear</button>
      <button ion-button (click)="execSQL(sql_stm.value)" color="secondary">ExecSQL</button>
      <button ion-button (click)="closeDB()" color="danger">Close DB</button>
      <ion-input style="height: 200px" placeholder="Enter a description" [(ngModel)]="textArea"></ion-input>
      <button ion-button full color="dark" (click)="clear()">Clear</button>
    </ion-content>
    

    home.ts

    import { Component, OnInit } from '@angular/core';
    import { NavController } from 'ionic-angular';
    @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
    })
    export class HomePage implements OnInit{
      textArea: string;
      db = null;
      dbConfig = {
        name: 'demo.db',
        key: '1234',
        location: 'default'
      };
      constructor(public navCtrl: NavController) {
        this.textArea = "";
      }
      ngOnInit() {
        this.updateTextArea(JSON.stringify(Object.keys(window)));
      }
      selfTest() {
        document.addEventListener('deviceready', function() {
          window['sqlitePlugin'].selfTest(() => {
            this.updateTextArea('SELF test OK');
          });
        });
      }
      echoTest() {
        document.addEventListener('deviceready', function() {
          window['sqlitePlugin'].echoTest(() => {
            this.updateTextArea('ECHO test OK');
          });
        });
      }
      openDB() {
        document.addEventListener('deviceready', () => {
          this.db = (<any>window).sqlitePlugin.openDatabase(this.dbConfig);
        });
      }
      execSQL(sql) {
        // const sql = 'INSERT "main"."db_test" VALUES (1);';
        this.db.executeSql(sql, [], rs => {
          this.updateTextArea(JSON.stringify(rs));
        }, error => {
          this.updateTextArea(JSON.stringify(error.message));
        });
      }
      updateTextArea(text) {
        this.textArea = this.textArea + '\n' + text;
      }
      closeDB() {
        this.db.close();
        alert("Close DB");
      }
      clear() {
        this.textArea = "";
      }
    }
    
  3. 测试通过 PRAGMA rekey='****' 改变密码语句可以使用。

  4. 关于SQLite加速,参考《提升SQLite数据插入效率低、速度慢的方法》。因为SQLCipher是JavaScript的封装,并没有提供全部的 C 导出函数,所以分析过后,只能从三个层面加速 SQL

    • 显式开启事务,SQLCipher 天然提供 db.transaction 接口。
    • 批量提交 SQL 语句,SQLCipher 推荐使用 db.sqlBatch 接口。
    • 写同步(synchronous),使用 PRAGMA 语句 关闭写同步:PRAGMA synchronous = OFF;

参考资料:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,042评论 25 707
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,360评论 2 44
  • 前言:用cordova开发hybrid app的过程中,由于是html5开发的app,在手机上很多权限受限制...
    京东内部优惠券阅读 5,295评论 5 65
  • 小女子践行第五天。 互联网时代真是一个打碎的世界,碎到无法拼凑又随意捏合,而且捏合到以前任何时代都无法达到的程度。...
    浅滩小贝阅读 185评论 0 1
  • 年纪越大,需要扮演的角色越多,需要承担的责任越重。 人在小时候,就是两条线的交点。一条主线是在家做好孩子,另外一条...
    三月南国阅读 260评论 0 0