在IOS中使用DES算法对Sqlite

数据库进行内容加密存储并读取解密

涉及知识点:

  1、DES加密算法;

  2、OC对Sqlite数据库的读写;

  3、IOS APP文件存储的两种方式及读取方式。

以下是各个知识点的讲解:

  1、DES算法详述

  DES算法把64位的明文输入块变為64位的密文输出块,它所使用的密钥也是64位,其功能是把输入的64位数据块按位重新组合,并把输出分為L0、R0两部分,每部分各长32位,其置换规则见下表:

58,50,12,34,26,18,10,2,60,52,44,36,28,20,12,4,
  62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
  57,49,41,33,25,17, 9,1,59,51,43,35,27,19,11,3,
  61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,

  即将输入的第58位换到第一位,第50位换到第2位,...,依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0 是右32位,例:设置换前的输入值為D1D2D3......D64,则经过初始置换后的结果為:L0=D550...D8;R0=D57D49...D7。

  经过26次迭代运算后。得到L16、R16,将此作為输入,进行逆置换,即得到密文输出。逆置换正好是初始置的逆运算,例如,第1位经过初始置换后,处於第40位,而通过逆置换,又将第40位换回到第1位,其逆置换规则如下表所示:

  40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,
  38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,
  36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,
  34,2,42,10,50,18,58 26,33,1,41, 9,49,17,57,25,

放大换位表

  32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10,11,
  12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21,
  22,23,24,25,24,25,26,27,28,29,28,29,30,31,32, 1,

单纯换位表

  16,7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
  2,8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,

  在f(Ri,Ki)算法描述图中,S1,S2...S8為选择函数,其功能是把6bit数据变為4bit数据。下面给出选择函数Si(i=1,2......8)的功能表:
选择函数Si

S1:
  14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
  0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
  4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
  15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
S2:
  15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
  3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
  0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
  13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
S3:
  10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
  13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
  13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
  1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
S4:
  7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
  13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
  10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
  3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
S5:
  2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
  14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
  4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
  11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
S6:
  12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
  10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
  9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
  4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
S7:
  4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
  13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
  1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
  6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
S8:
  13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
  1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
  7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
  2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11,

在此以S1為例说明其功能,我们可以看到:在S1中,共有4行数据,命名為0,1、2、3行;每行有16列,命名為0、1、2、3,......,14、15列。

  现设输入為: D=D1D2D3D4D5D6
令:列=D2D3D4D5
  行=D1D6

  然后在S1表中查得对应的数,以4位二进製表示,此即為选择函数S1的输出。下面给出子密钥Ki(48bit)的生成算法

  从子密钥Ki的生成算法描述图中我们可以看到:初始Key值為64位,但DES算法规定,其中第8、16、......64位是奇偶校验位,不参与DES运算。故Key 实际可用位数便只有56位。即:经过缩小选择换位表1的变换后,Key 的位数由64 位变成了56位,此56位分為C0、D0两部分,各28位,然后分别进行第1次循环左移,得到C1、D1,将C1(28位)、D1(28位)合併得到56位,再经过缩小选择换位2,从而便得到了密钥K0(48位)。依此类推,便可得到K1、K2、......、K15,不过需要注意的是,16次循环左移对应的左移位数要依据下述规则进行:

循环左移位数
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
  以上介绍了DES算法的加密过程。DES算法的解密过程是一样的,区别仅仅在於第一次迭代时用子密钥K15,第二次K14、......,最后一次用K0,算法本身并没有任何变化。
DES算法具有极高安全性,到目前為止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥的穷举空间為256,这意味著如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随著科学技术的发展,当出现超高速计算机后,我们可考虑把DES密钥的长度再增长一些,以此来达到更高的保密程度。

2、oc对Sqlite数据库的读写操作语句:

对数据库的读写往往设计数据库的创建,打开,以及增删改查,在使用OC对Sqlite的以上几种操作代码是用字符串包装的sql语句,具体使用见代码。

3、APP中数据、文件的存储有两种方式,第一种是关于软件本身的数据和文件,可以直接放在软件的结构框架中,也就是头文件和.m文件所在的树中,也可以放在沙盒中,两种读取方式不一样,放在结构树中的只能读,不能写入,而放在沙盒中的可以进行读写操作,所以涉及用户要修改的东西、或者软件经过用户使用之后会修改的东西要放在沙盒中。据图两种读写方式见代码。

以下代码实现的功能是把存放在结构树中的Sqlite数据库进行读取,并对除了id和use之外的所有内容使用del算法进行加密,加密后的按照数据库原先的结构存放在沙盒中新建的数据库中,如果需要读取,可以通过查询id和use进行读取并对其他字段使用des 加密算法进行解密。

 #import "ViewController.h"
#import "jiami.h"
#include "FMDatabase.h"
@interface ViewController (){
FMDatabase *mydb;
FMDatabase *mydbins;
NSString *key;
jiami *secret;
UIButton *myBtn;
UITextField *textField;
} @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// 创建加密实体,以后使用实体调用加密方法,要加密的字符串和key以参数的方式传入
key = @"secret";
secret= [[jiami alloc]init]; // 读取文件结构中的数据库
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"meridianPoint" ofType:@"sqlite"];
mydbins = [[FMDatabase alloc]initWithPath:bundlePath]; // 在沙盒中创建数据库
// 创建路径
NSString *documentsPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/mydb.sqlite"];
// 创建数据库
mydb = [[FMDatabase alloc]initWithPath:documentsPath];
// 创建表的语句
NSString *tablecreate = @"create table if not exists mytable(id text primary key,meridian_id text,name text,property1_id text,property2_id text,property3_id text,use text,position text,dissection text,indications text,synergy text,acupuncture text,note text,x text,y text,dict text,py_name text,meridian_text text,GB text)";
// 打开数据库,并使用创建表的语句创建表,创建完成后返回一个bool值,根据bool值判断是否创建成功
if ([mydb open]) {
BOOL yesOrNo = [mydb executeUpdate:tablecreate];
if (yesOrNo) {
NSLog(@"sucess");
}else{
NSLog(@"fail");
}
// 操作完成后要关闭数据库
[mydb close];
} // 打开要操作的两个数据库
if ([mydbins open]&&[mydb open]) {
for (int i =; i<; i++) { // 查询语句的创建
NSString *sqlString=[NSString stringWithFormat:@"select * from acupoint_cn where id = %d",i];
// 查询并把查询的结果赋值给结果集
FMResultSet *result = [mydbins executeQuery:sqlString]; while ([result next]) {
// 读取查询到的记录的每个字段
NSString *idd = [result stringForColumn:@"id"];
NSString *meridian_idd = [result stringForColumn:@"meridian_id"];
NSString *named = [result stringForColumn:@"name"];
NSString *property1_idd = [result stringForColumn:@"property1_id"];
NSString *property2_idd = [result stringForColumn:@"property2_id"];
NSString *property3_idd = [result stringForColumn:@"property3_id"];
NSString *positiond = [result stringForColumn:@"position"];
NSString *use = [result stringForColumn:@"use"];
NSString *dissectiond = [result stringForColumn:@"dissection"];
NSString *indicationsd = [result stringForColumn:@"indications"];
NSString *synergyd = [result stringForColumn:@"synergy"];
NSString *acupunctured = [result stringForColumn:@"acupuncture"];
NSString *xd = [result stringForColumn:@"x"];
NSString *yd = [result stringForColumn:@"y"];
NSString *noted = [result stringForColumn:@"note"];
NSString *py_named = [result stringForColumn:@"py_name"];
NSString *dictd = [result stringForColumn:@"dict"];
NSString *meridian_textd = [result stringForColumn:@"meridian_text"];
NSString *GBd = [result stringForColumn:@"GB"]; // 对除了id和use的字段进行加密
NSString *meridian_id = [secret encryptUseDES:meridian_idd key:key];
NSString *name = [secret encryptUseDES:named key:key];
NSString *property1_id = [secret encryptUseDES:property1_idd key:key];
NSString *property2_id = [secret encryptUseDES:property2_idd key:key];
NSString *property3_id = [secret encryptUseDES:property3_idd key:key];
NSString *position = [secret encryptUseDES:positiond key:key];
NSString *dissection = [secret encryptUseDES:dissectiond key:key];
NSString *indications = [secret encryptUseDES:indicationsd key:key];
NSString *synergy = [secret encryptUseDES:synergyd key:key];
NSString *acupuncture = [secret encryptUseDES:acupunctured key:key];
NSString *x = [secret encryptUseDES:xd key:key];
NSString *y = [secret encryptUseDES:yd key:key];
NSString *note = [secret encryptUseDES:noted key:key];
NSString *py_name = [secret encryptUseDES:py_named key:key];
NSString *dict = [secret encryptUseDES:dictd key:key];
NSString *meridian_text = [secret encryptUseDES:meridian_textd key:key];
NSString *GB = [secret encryptUseDES:GBd key:key]; // 把加密后的数据存入沙盒中的数据库,使用insert into语句
[mydb executeUpdate:@"insert into mytable(id, meridian_id,name,property1_id,property2_id,property3_id,use,position,dissection,indications ,synergy,acupuncture,note,x,y,dict,py_name,meridian_text,GB) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",idd,meridian_id,name,property1_id,property2_id,property3_id,use,position,dissection,indications,synergy,acupuncture,note,x,y,dict,py_name,meridian_text,GB]; } }
// 操作完成后关闭两个数据库
[mydbins close];
[mydb close]; } // button
myBtn= [[UIButton alloc]initWithFrame:CGRectMake(, , , )];
myBtn.backgroundColor = [UIColor orangeColor];
myBtn.layer.cornerRadius = ;
myBtn.layer.masksToBounds = YES;
myBtn.enabled = YES;
[myBtn setTitle:@"开始按钮" forState:UIControlStateNormal];
[myBtn addTarget:self action:@selector(myBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myBtn]; // textfield
textField = [[UITextField alloc]initWithFrame:CGRectMake(, , , )];
[textField setBackgroundColor:[UIColor lightGrayColor]];
textField.placeholder = @"请输入要查询的病症";
[self.view addSubview:textField]; } //点击按钮时进行查询(此功能未完善)
-(void)myBtnAction :(UIButton*)sender{
if ([mydb open]) { FMResultSet *result = [mydb executeQuery:@"select * from mytable where use like ?%",textField.text];
while ([result next]) {
NSString *use = [result stringForColumn:@"use"];
// NSString *useunsecret = [secret decryptUseDES:use key:key];
textField.text = use;
}
[mydb close];
}
} //文本输入框输入完成后,点击其他地方收回键盘
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
} @end

需要注意的地方:

1、打开数据库并进行操作使用以下语句,在打开时使用判断,如果未打开则提示未打开的原因,如果打开了,进行完操作后一定要关闭数据库:

 if([数据库名 open]){
操作语句;
操作语句;
操作语句;
...... [数据库名 close]; }else{ NSLog(@"数据库因。。。未打开"); }

2、查询语句的结果为一个集合,需要使用如下语句去读取集合中的内容,如果想读取其他字段的内容,只需要把下面代码中的id换成对应的字段即可:

 //        查询语句的创建
NSString *sqlString=[NSString stringWithFormat:@"select * from acupoint_cn where id = %d",i];
// 查询并把查询的结果赋值给结果集
FMResultSet *result = [mydbins executeQuery:sqlString]; while ([result next]) {
// 读取查询到的记录的每个字段
NSString *idd = [result stringForColumn:@"id"];
}

3、可以把查询语句直接作为executeQuery的参数,但这样有时候在做格式替换的时候比较麻烦,比如下面代码中i是for循环的变量,比较简单且不容易出错的做法是先构建一个字符串,然后把这个字符串当作executeQuery的参数。

//        查询语句的创建
NSString *sqlString=[NSString stringWithFormat:@"select * from acupoint_cn where id = %d",i];
// 查询并把查询的结果赋值给结果集
FMResultSet *result = [mydbins executeQuery:sqlString];

在IOS中使用DES算法对Sqlite数据库进行内容加密存储并读取解密的更多相关文章

  1. iOS中 用FMDB封装一个SQLite数据库

    建立一个单例: DataBaseHandle.h #import <Foundation/Foundation.h> @class PersonModel; @class FMDataba ...

  2. IOS开发-UI学习-sqlite数据库的操作

    IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这 ...

  3. 在VB中利用Nuget包使用SQLite数据库和Linq to SQLite

    上午解决了在C#中利用Nuget包使用SQLite数据库和Linq to SQLite,但是最后生成的是C#的cs类文件,对于我这熟悉VB而对C#白痴的来说怎么能行呢? 于是下午接着研究,既然生成的是 ...

  4. 聊聊密码学中的DES算法

    用心分享,共同成长 没有什么比你每天进步一点点更实在了 本文已经收录至我的github,欢迎大家踊跃star 和 issues. https://github.com/midou-tech/artic ...

  5. iOS中使用FMDB事务批量更新数据库

    今天比较闲看到大家在群里讨论关于数据库操作的问题,其中谈到了"事务"这个词,坦白讲虽然作为计算机专业的学生,在上学的时候确实知道存储过程.触发器.事务等等这些名词的概念,但是由于毕 ...

  6. 在C#中利用Nuget包使用SQLite数据库和Linq to SQLite

    本来是学习在VB中使用SQLite数据库和Linq to SQLite,结果先学习到了在C#中使用SQLite数据库和Linq to SQLite的方法,写出来与大家共同学习.(不知道算不算不务正业) ...

  7. Electron中使用sql.js操作SQLite数据库

    推荐sql.js——一款纯js的sqlite工具. 一.关于sql.js sql.js(https://github.com/kripken/sql.js)通过使用Emscripten编译SQLite ...

  8. iOS:面向对象的思想使用sqlite数据库

    SQLite支持的常见数据类型如下所示. –INTEGER 有符号的整数类型 –REAL 浮点类型 –TEXT 字符串类型,采用UTF-8和UTF-16字符编码 –BLOB 二进制大对象类型,能够存放 ...

  9. 在Android中afinal框架下实现sqlite数据库版本升级的办法

    上一篇文章采用的是SQLiteOpenHelper中的onUpgrade方法实现数据库的升级. 首先获取Context: private Context mContext=this; 然后实现Fina ...

随机推荐

  1. POJ 2773 Happy 2006(欧几里德算法)

    题意:给出一个数m,让我们找到第k个与m互质的数. 方法:这题有两种方法,一种是欧拉函数+容斥原理,但代码量较大,另一种办法是欧几里德算法,比较容易理解,但是效率很低. 我这里使用欧几里德算法,欧几里 ...

  2. 【Qt开发】修改源码文件的编码格式的小技巧 .

    默认情况下,代码文件应该以utf-8的格式来存储的.而如果在代码文件的转移或者上传下载过程中,弄乱了文件的编码格式,一般会出现乱码的情况. 例如windows系统下,中文就很容易出现乱码,如下图,文件 ...

  3. AS3条件编译

    package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { s ...

  4. Spring的事务传播机制

    1.事务传播类型     新建事务 required required_new   - 挂起当前    非事务方式运行 supports not_supported  - 挂起当前 never    ...

  5. IOS小工具以及精彩的博客

    IOS小工具以及精彩的博客 工具 Log Guru是一个收集Log的小工具, 可以在 Mac 上查看 iOS 设备的实时系统日志. 现在可以直接高亮显示在 FIR.im 上安装 app 失败的原因.后 ...

  6. 一个java解析xml的简单例子

    java解析xml,主要是通过Dom4j实现的,很多场合都会用到此功能,需要解析XML文件. 下面是一个简单的解析XML文件的例子: import java.util.Iterator; import ...

  7. java source map

    Chrome 更新后出现了 jquery.min.map 404  (Not Found) 的信息 这个到底是什么东西?查询了一下,得到了以下资料 JQuery 官方解释 摘录一下內容 从 jQuer ...

  8. Chapter 1 First Sight——4

    Charlie gave me an awkward, one-armed hug when I stumbled my way off the plane. 当我让我蹒跚的从飞机上下来,查理斯单手给 ...

  9. Cannot find PHPUnit in include path phpstorm

    This is the way to do it without using composer, and using your global phpunit.Phpunit now comes wit ...

  10. java项目开发第六天——天若有情天亦老,人间正道是沧桑

    今天讲解的东西是数据库连接,一天下来还是相对轻松的,这个组长也是够轻松的,队员加载的界面自己也是导入不了,最后也是不了了之,还是加油赶赶吧.看看严嘉那组的界面,最后就是呵呵.但是学长看完后(研究生,同 ...