zoukankan      html  css  js  c++  java
  • 董淳光之SQLITE3 使用总结(4)

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

    /*** 下面是编译时提示缺少的函数 ***/

     

    /** 这个函数不需要做任何处理,获取密钥的部分在下面 DeriveKey 函数里实现 **/

    void sqlite3CodecGetKey(sqlite3* db, int nDB, void** Key, int* nKey)

    {

    return ;

    }

     

    /*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/

    int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen);

     

    /**

    这个函数好像是 sqlite 3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数

    这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响

    **/

    void sqlite3_activate_see(const char* right )

    {   

    return;

    }

     

    int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);

     

    int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);

     

     

     

    /***

    下面是上面的函数的辅助处理函数

    ***/

     

    // 从用户提供的缓冲区中得到一个加密密钥

    // 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展

    static unsigned char * DeriveKey(const void *pKey, int nKeyLen);

    //创建或更新一个页的加密算法索引.此函数会申请缓冲区.

    static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting);

    //加密/解密函数, 被pager调用

    void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode);

    //设置密码函数

    int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize);

    // 修改密码函数

    int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize);

    //销毁一个加密块及相关的缓冲区,密钥.

    static void DestroyCryptBlock(LPCryptBlock pBlock);

    static void * sqlite3pager_get_codecarg(Pager *pPager);

    void sqlite3pager_set_codec(Pager *pPager,void *(*xCodec)(void*,void*,Pgno,int),void*pCodecArg    );

     

     

     

    //加密/解密函数, 被pager调用

    void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode)

    {

    LPCryptBlock pBlock = (LPCryptBlock)pArg;

    unsigned int dwPageSize = 0;

     

    if (!pBlock) return data;

     

    // 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.

    if (nMode != 2)

    {

         PgHdr *pageHeader;

         pageHeader = DATA_TO_PGHDR(data);

         if (pageHeader->pPager->pageSize != pBlock->PageSize)

         {

              CreateCryptBlock(0, pageHeader->pPager, pBlock);

         }

    }

     

    switch(nMode)

    {

    case 0: // Undo a "case 7" journal file encryption

    case 2: //重载一个页

    case 3: //载入一个页

         if (!pBlock->ReadKey) break;

     

     

         dwPageSize = pBlock->PageSize;

         My_DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE );  /*调用我的解密函数*/

     

         break;

    case 6: //加密一个主数据库文件的页

         if (!pBlock->WriteKey) break;

     

         memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);

         data = pBlock->Data + CRYPT_OFFSET;

     

     

         dwPageSize = pBlock->PageSize;

         My_Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE ); /*调用我的加密函数*/

         break;

    case 7: //加密事务文件的页

         /*在正常环境下, 读密钥和写密钥相同. 当数据库是被重新加密的,读密钥和写密钥未必相同.

         回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥,

         这是为了保证与读取原始数据的密钥相同.

         */

         if (!pBlock->ReadKey) break;

     

         memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize);

         data = pBlock->Data + CRYPT_OFFSET;

     

     

         dwPageSize = pBlock->PageSize;

         My_Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ); /*调用我的加密函数*/

         break;

    }

     

    return data;

    }

     

     

     

     

    //销毁一个加密块及相关的缓冲区,密钥.

    static void DestroyCryptBlock(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);

    }

     

    static void * sqlite3pager_get_codecarg(Pager *pPager)

    {

    return (pPager->xCodec) ? pPager->pCodecArg: NULL;

    }

    // 从用户提供的缓冲区中得到一个加密密钥

    static unsigned char * DeriveKey(const void *pKey, int nKeyLen)

    {

    unsigned char *  hKey = NULL;

    int j;

     

    if( pKey == NULL || nKeyLen == 0 )

    {

         return NULL;

    }

     

    hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + 1 );

    if( hKey == NULL )

    {

         return NULL;

    }

    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, pKey, DB_KEY_LENGTH_BYTE );

    }

     

    return hKey;

    }

     

     

    //创建或更新一个页的加密算法索引.此函数会申请缓冲区.

    static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting)

    {

    LPCryptBlock pBlock;

     

    if (!pExisting) //创建新加密块

    {

         pBlock = sqliteMalloc(sizeof(CryptBlock));

         memset(pBlock, 0, sizeof(CryptBlock));

         pBlock->ReadKey = hKey;

         pBlock->WriteKey = hKey;

         pBlock->PageSize = pager->pageSize;

         pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET);

    }

    else //更新存在的加密块

    {

         pBlock = pExisting;

         if ( pBlock->PageSize != pager->pageSize && !pBlock->Data){

              sqliteFree(pBlock->Data);

              pBlock->PageSize = pager->pageSize;

              pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET);

         }

    }

     

     

    memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);

     

    return pBlock;

    }

     

    /*

    ** Set the codec for this pager

    */

    void sqlite3pager_set_codec(

                                 Pager *pPager,

                                 void *(*xCodec)(void*,void*,Pgno,int),

                                void *pCodecArg

                                 )

    {

    pPager->xCodec = xCodec;

    pPager->pCodecArg = pCodecArg;

    }

     

  • 相关阅读:
    mysql子查询
    hibernate lazy属性true false extra 抓取策略
    unittest下,生成的测试报告
    python创建excel文件,并进行读与存操作
    configparser模块简介
    PyCharm里面的c、m、F、f、v、p分别代表什么含义?
    Python之路(第十七篇)logging模块
    configparser模块简介
    python中os.sep的作用以及sys._getframe().f_back.f_code.co_xxx的含义
    os.getcwd()和os.path.realpath(__file__)的区别
  • 原文地址:https://www.cnblogs.com/iapp/p/3631770.html
Copyright © 2011-2022 走看看