董淳光之SQLITE3 使用总结(5)
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;//主数据库,没有指定密钥所以没有加密. } 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); }
转自http://www.sqlite.com.cn/MySqlite/6/411.Html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |