董淳光之SQLITE3 使用总结(4)
http://www.sqlite.com.cn/MySqlite/6/410.Html /***下面是编译时提示缺少的函数***/
/**这个函数不需要做任何处理,获取密钥的部分在下面DeriveKey函数里实现**/ voidsqlite3CodecGetKey(sqlite3* db,intnDB,void** Key,int* nKey) { return; } /*被sqlite和sqlite3_key_interop调用,附加密钥到数据库.*/ intsqlite3CodecAttach(sqlite3 *db,intnDb,constvoid*pKey,intnKeyLen); /** 这个函数好像是sqlite3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数 这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响 **/ voidsqlite3_activate_see(constchar* right ) { return; } intsqlite3_key(sqlite3 *db,intnKey); intsqlite3_rekey(sqlite3 *db,intnKey); /*** 下面是上面的函数的辅助处理函数 ***/
//从用户提供的缓冲区中得到一个加密密钥 //用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展 staticunsignedchar* DeriveKey(constvoid*pKey,intnKeyLen); //创建或更新一个页的加密算法索引.此函数会申请缓冲区. staticLPCryptBlock CreateCryptBlock(unsignedchar* hKey,Pager *pager,LPCryptBlock pExisting); //加密/解密函数,被pager调用 void* sqlite3Codec(void*pArg,unsignedchar*data,Pgno nPageNum,intnMode); //设置密码函数 int__stdcallsqlite3_key_interop(sqlite3 *db,intnKeySize); //修改密码函数 int__stdcallsqlite3_rekey_interop(sqlite3 *db,intnKeySize); //销毁一个加密块及相关的缓冲区,密钥. staticvoidDestroyCryptBlock(LPCryptBlock pBlock); staticvoid* sqlite3pager_get_codecarg(Pager *pPager); voidsqlite3pager_set_codec(Pager *pPager,void*(*xCodec)(void*,void*,Pgno,int),void*pCodecArg); //加密/解密函数,intnMode) { LPCryptBlock pBlock = (LPCryptBlock)pArg; unsignedintdwPageSize = 0; if(!pBlock)returndata; //确保pager的页长度和加密块的页长度相等.如果改变,就需要调整. if(nMode != 2) { PgHdr *pageHeader; pageHeader = DATA_TO_PGHDR(data); if(pageHeader->pPager->pageSize != pBlock->PageSize) { CreateCryptBlock(0,pageHeader->pPager,pBlock); } } switch(nMode) { case0:// Undo a "case 7" journal file encryption case2://重载一个页 case3://载入一个页 if(!pBlock->ReadKey)break; dwPageSize = pBlock->PageSize; My_DeEncrypt_Func(data,dwPageSize,pBlock->ReadKey,DB_KEY_LENGTH_BYTE );/*调用我的解密函数*/
break; case6://加密一个主数据库文件的页 if(!pBlock->WriteKey)break; memcpy(pBlock->Data + CRYPT_OFFSET,data,pBlock->PageSize); data = pBlock->Data + CRYPT_OFFSET; dwPageSize = pBlock->PageSize; My_Encrypt_Func(data,pBlock->WriteKey,DB_KEY_LENGTH_BYTE );/*调用我的加密函数*/ break; case7://加密事务文件的页 /*在正常环境下,读密钥和写密钥相同.当数据库是被重新加密的,读密钥和写密钥未必相同. 回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥, 这是为了保证与读取原始数据的密钥相同. */ if(!pBlock->ReadKey)break; memcpy(pBlock->Data + CRYPT_OFFSET,pBlock->PageSize); data = pBlock->Data + CRYPT_OFFSET; dwPageSize = pBlock->PageSize; My_Encrypt_Func( data,DB_KEY_LENGTH_BYTE );/*调用我的加密函数*/ break; } returndata; } //销毁一个加密块及相关的缓冲区,密钥. staticvoidDestroyCryptBlock(LPCryptBlock pBlock) { //销毁读密钥. if(pBlock->ReadKey){ sqliteFree(pBlock->ReadKey); } //如果写密钥存在并且不等于读密钥,也销毁. if(pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey){ sqliteFree(pBlock->WriteKey); } if(pBlock->Data){ sqliteFree(pBlock->Data); } //释放加密块. sqliteFree(pBlock); } staticvoid* sqlite3pager_get_codecarg(Pager *pPager) { return(pPager->xCodec) ? pPager->pCodecArg: NULL; } //从用户提供的缓冲区中得到一个加密密钥 staticunsignedchar* DeriveKey(constvoid*pKey,intnKeyLen) { unsignedchar*hKey = NULL; intj; if( pKey == NULL || nKeyLen == 0 ) { returnNULL; } hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + 1 ); if( hKey == NULL ) { returnNULL; } hKey[ DB_KEY_LENGTH_BYTE ] = 0; if( nKeyLen < DB_KEY_LENGTH_BYTE ) { memcpy( hKey,pKey,nKeyLen );//先拷贝得到密钥前面的部分 j = DB_KEY_LENGTH_BYTE - nKeyLen; //补充密钥后面的部分 memset(hKey + nKeyLen,DB_KEY_PADDING,j); } else {//密钥位数已经足够,直接把密钥取过来 memcpy(hKey,DB_KEY_LENGTH_BYTE ); } returnhKey; } //创建或更新一个页的加密算法索引.此函数会申请缓冲区. staticLPCryptBlock CreateCryptBlock(unsignedchar* hKey,LPCryptBlock pExisting) { LPCryptBlock pBlock; if(!pExisting)//创建新加密块 { pBlock = sqliteMalloc(sizeof(CryptBlock)); memset(pBlock,sizeof(CryptBlock)); pBlock->ReadKey = hKey; pBlock->WriteKey = hKey; pBlock->PageSize = pager->pageSize; pBlock->Data = (unsignedchar*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET); } else//更新存在的加密块 { pBlock = pExisting; if( pBlock->PageSize != pager->pageSize && !pBlock->Data){ sqliteFree(pBlock->Data); pBlock->PageSize = pager->pageSize; pBlock->Data = (unsignedchar*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET); } } memset(pBlock->Data,pBlock->PageSize + CRYPT_OFFSET); returnpBlock; } /* ** Set the codec for this pager */ voidsqlite3pager_set_codec( Pager *pPager, void*(*xCodec)(void*, void*pCodecArg ) { pPager->xCodec = xCodec; pPager->pCodecArg = pCodecArg; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- C++ 数字的反转实现实例
- c# – Clean Rebuild和Clean Build之间有什么区别
- c# – WPF工具包DataGridCell样式DataTrigger
- 详解Vue-基本标签和自定义控件
- ruby-on-rails – Rails和paperclip,删除记录但不
- ruby-on-rails – 渴望使用实例变量加载自定义连
- [Swift]LeetCode338. 比特位计数 | Counting Bit
- 钟表维修管理系统技术解析(六) 数据统计
- objective-c – 编写NSPredicate,如果条件不满足
- [软件设计] 控制反转(Inversion of Control)随想