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);
}
/*被sqlite和sqlite3_key_interop调用,附加密钥到数据库.*/
intsqlite3CodecAttach(sqlite3 *db,intnDb,intnKeyLen)
{
intrc = sqlITE_ERROR;
unsignedchar* hKey = 0;
//如果没有指定密匙,可能标识用了主数据库的加密或没加密.
if(!pKey || !nKeyLen)
{
if(!nDb)
{
returnsqlITE_OK;//主数据库,没有指定密钥所以没有加密.
}
{
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