董淳光之SQLITE3 使用总结(5)

前端之家收集整理的这篇文章主要介绍了董淳光之SQLITE3 使用总结(5)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.sqlite.com.cn/MySqlite/6/411.Html


intsqlite3_key(sqlite3 *db,constvoid*pKey,intnKey)

{

returnsqlite3_key_interop(db,pKey,nKey);

}

intsqlite3_rekey(sqlite3 *db,intnKey)

{

returnsqlite3_rekey_interop(db,nKey);

}

/*sqlitesqlite3_key_interop调用,附加密钥到数据库.*/

intsqlite3CodecAttach(sqlite3 *db,intnDb,intnKeyLen)

{

intrc = sqlITE_ERROR;

unsignedchar* hKey = 0;

//如果没有指定密匙,可能标识用了主数据库的加密或没加密.

if(!pKey || !nKeyLen)

{

if(!nDb)

{

returnsqlITE_OK;//数据库,没有指定密钥所以没有加密.

}

else//附加数据库,使用主数据库的密钥.

{

//获取数据库的加密块并复制密钥给附加数据库使用

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));

if(!pBlock)returnsqlITE_OK;//数据库没有加密

if(!pBlock->ReadKey)returnsqlITE_OK;//没有加密

memcpy(pBlock->ReadKey,&hKey,16);

}

}

else//用户提供了密码,从中创建密钥.

{

hKey = DeriveKey(pKey,nKeyLen);

}

//创建一个新的加密块,并将解码器指向新的附加数据库.

if(hKey)

{

LPCryptBlock pBlock = CreateCryptBlock(hKey,sqlite3BtreePager(db->aDb[nDb].pBt),NULL);

sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt),sqlite3Codec,pBlock);

rc = sqlITE_OK;

}

returnrc;

}

// Changes the encryption key for an existing database.

int__stdcallsqlite3_rekey_interop(sqlite3 *db,intnKeySize)

{

Btree *pbt = db->aDb[0].pBt;

Pager *p = sqlite3BtreePager(pbt);

LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);

unsignedchar* hKey = DeriveKey(pKey,nKeySize);

intrc = sqlITE_ERROR;

if(!pBlock && !hKey)returnsqlITE_OK;

//重新加密一个数据库,改变pager的写密钥,读密钥依旧保留.

if(!pBlock)//加密一个未加密的数据库

{

pBlock = CreateCryptBlock(hKey,p,NULL);

pBlock->ReadKey = 0;//原始数据库未加密

sqlite3pager_set_codec(sqlite3BtreePager(pbt),pBlock);

}

else//改变已加密数据库的写密钥

{

pBlock->WriteKey = hKey;

}

//开始一个事务

rc = sqlite3BtreeBeginTrans(pbt,1);

if(!rc)

{

//用新密钥重写所有的页到数据库

Pgno nPage = sqlite3PagerPagecount(p);

Pgno nSkip = PAGER_MJ_PGNO(p);

void*pPage;

Pgno n;

for(n = 1; rc == sqlITE_OK && n <= nPage; n ++)

{

if(n == nSkip)continue;

rc = sqlite3PagerGet(p,n,&pPage);

if(!rc)

{

rc = sqlite3PagerWrite(pPage);

sqlite3PagerUnref(pPage);

}

}

}

//如果成功,提交事务。

if(!rc)

{

rc = sqlite3BtreeCommit(pbt);

}

//如果失败,回滚。

if(rc)

{

sqlite3BtreeRollback(pbt);

}

//如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。

if(!rc)

{

if(pBlock->ReadKey)

{

sqliteFree(pBlock->ReadKey);

}

pBlock->ReadKey = pBlock->WriteKey;

}

else//如果失败,销毁当前的写密钥,并恢复为当前的读密钥。

{

if(pBlock->WriteKey)

{

sqliteFree(pBlock->WriteKey);

}

pBlock->WriteKey = pBlock->ReadKey;

}

//如果读密钥和写密钥皆为空,就不需要再对页进行编解码。

//销毁加密块并移除页的编解码器

if(!pBlock->ReadKey && !pBlock->WriteKey)

{

sqlite3pager_set_codec(p,NULL,NULL);

DestroyCryptBlock(pBlock);

}

returnrc;

}

/***

下面是加密函数的主体

***/

int__stdcallsqlite3_key_interop(sqlite3 *db,intnKeySize)

{

returnsqlite3CodecAttach(db,nKeySize);

}

//释放与一个页相关的加密块

voidsqlite3pager_free_codecarg(void*pArg)

{

if(pArg)

DestroyCryptBlock((LPCryptBlock)pArg);

}

#endif//#ifdef sqlITE_HAS_CODEC

、后记

写此教程,可不是一个累字能解释。

但是我还是觉得欣慰的,因为我很久以前就想写sqlite的教程,一来自己备忘,二而已造福大众,大家不用再走弯路。

本人第一次写教程,不足的地方请大家指出。

本文可随意转载、修改、引用。但无论是转载、修改、引用,都请附带我的名字:董淳光。以示对我劳动的肯定。

原文链接:https://www.f2er.com/sqlite/201687.html

猜你在找的Sqlite相关文章