int sqlite3_key(sqlite3 *db,const void *pKey,int nKey)
{
return sqlite3_key_interop(db,pKey,nKey);
}
int sqlite3_rekey(sqlite3 *db,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal">return sqlite3_rekey_interop(db,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal">/*被sqlite 和 sqlite3_key_interop 调用,附加密钥到数据库.*/
int sqlite3CodecAttach(sqlite3 *db,int nDb,int nKeyLen)
int rc = sqlITE_ERROR;
unsigned char* hKey = 0;
//如果没有指定密匙,可能标识用了主数据库的加密或没加密.
if (!pKey || !nKeyLen)
{
if (!nDb)
return sqlITE_OK; //主数据库,没有指定密钥所以没有加密.
}
LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));
if (!pBlock) return sqlITE_OK; //主数据库没有加密
if (!pBlock->ReadKey) return sqlITE_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;
return rc;
// Changes the encryption key for an existing database.
int __stdcall sqlite3_rekey_interop(sqlite3 *db,int nKeySize)
Btree *pbt = db->aDb[0].pBt;
Pager *p = sqlite3BtreePager(pbt);
LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);
unsigned char * hKey = DeriveKey(pKey,nKeySize);
int rc = sqlITE_ERROR;
if (!pBlock && !hKey) return sqlITE_OK;
//重新加密一个数据库,改变pager的写密钥,读密钥依旧保留.
if (!pBlock) //加密一个未加密的数据库
{
pBlock = CreateCryptBlock(hKey,p,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal"> pBlock->ReadKey = 0; // 原始数据库未加密
sqlite3pager_set_codec(sqlite3BtreePager(pbt),230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal">}
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);
// 如果成功,提交事务。
rc = sqlite3BtreeCommit(pbt);
// 如果失败,回滚。
if (rc)
sqlite3BtreeRollback(pbt);
// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。
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,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal"> DestroyCryptBlock(pBlock);
return rc;
/***
下面是加密函数的主体
***/
int __stdcall sqlite3_key_interop(sqlite3 *db,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal"> return sqlite3CodecAttach(db,230) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; text-align: left;" class="MsoNormal">// 释放与一个页相关的加密块
void sqlite3pager_free_codecarg(void *pArg)
if (pArg)
DestroyCryptBlock((LPCryptBlock)pArg);
#endif //#ifdef sqlITE_HAS_CODEC