SQLite source code encryption, and some other articles

Source: Internet
Author: User
Tags assert crypt extend sqlite sqlite database

First, to encrypt the database

The above-mentioned content online already has a lot of information, although relatively scattered, but take a little time can still be found. Now this is the--database encryption, data is difficult to find. It may be that I do not have enough level of operation to find the corresponding data. However, I still find the complete steps to encrypt the SQLite database by using a limited amount of data that can be found online.

Here to mention, although SQLite is very useful, fast, small size. But the file it saves is clear text. If you do not believe you can open the database file with NotePad look, the inside of the insert content almost unobstructed. It is not our intention to reveal ourselves in such a naked way. Of course, if you use SQLite in embedded systems, smartphones, it is best not to encrypt, because these systems are limited in computing power, you as a new feature provider, can not put the user's limited computing power to spend all.

SQLite was born for the sake of speed. So SQLite itself does not encrypt the database, you know, if you choose the standard AES algorithm encryption, then there must be nearly 50% of the time spent on the encryption and decryption algorithm, or even more (performance depends mainly on your algorithm writing level and whether you can use the CPU to provide the underlying computing power, For example, MMX or SSE series instructions can greatly increase the speed of operation).

The free version of SQLite does not provide encryption, of course you can also choose their fee version, then you have to pay 2000 dollars, and is USD. I am not here to say that the payment of money is not good, if only for the database encryption to pay 2000 dollars, I do not think it can be zoned. Because I'm going to show you how to extend the encryption module for free SQLite--Do it yourself, which is what SQLite allows and it advocates.

So, let's start by extending the encryption module for the sqlite3.c file.

I.1 the necessary macros

By reading the Sqlite code (of course, not all finished reading, 60,000 lines of code, no line is my habit of style, I do not have so many eyes to see), I got two things clear:

SQLite is to support encryption extension;

You need to #define a macro to use the encryption extension.

This macro is Sqlite_has_codec.

You can define it in front of the code (or in the first line of the Sqlite3.h file):

#ifndef Sqlite_has_codec

#define Sqlite_has_codec


If you define this macro in your code, but you can compile it correctly, the operation should not be successful. Because you should be prompted by the compiler that there are some functions that cannot be linked. If you are using VC 2003, you can right click on your project in the "solution", then select "Properties", find "C + +", and then find "command line", add "/d" Sqlite_has_codec "" in it manually.

Define this macro, some of the code that is deliberately masked by Sqlite is used. This code is the interface for encryption and decryption.

Try compiling, VC will prompt you to have some function cannot link, because cannot find their implementation.

If you also use VC2003, you will get the following hint:

Error LNK2019: unresolved external symbol _sqlite3codecgetkey, which is referenced in function _attachfunc

Error LNK2019: unresolved external symbol _sqlite3codecattach, which is referenced in function _attachfunc

Error LNK2019: unresolved external symbol _sqlite3_activate_see, which is referenced in function _sqlite3pragma

Error LNK2019: unresolved external symbol _sqlite3_key, which is referenced in function _sqlite3pragma

Fatal error Lnk1120:4 an unresolved external command

This is normal, because SQLite only left the interface, and did not give the implementation.

Let me implement these interfaces below.

I.2 to implement the encryption and decryption interface function itself

If you really want me to go down from a www.sqlite.org online sqlite3.c file, directly explore the implementation of these interfaces, I think I do not have this ability.

Fortunately, there is some code on the Internet that has implemented this function. By referring to their code and the error hints given by the VC in the compilation, I finally sorted out the entire interface.

It is not so easy to implement these reserved interfaces, it is difficult to start again. I have written all the code, directly to the following instructions I copy to the sqlite3.c file corresponding to the location. I also provide a sqlite3.c file below that can be directly referenced or removed for use.

One thing to say here is that I have created another two files: crypt.c and crypt.h.

Where crypt.h is so defined:




Dong Chun-Write SQLITE encryption key function library



Key cryptographic functions


int My_encrypt_func (unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key);


Key decryption functions


int My_deencrypt_func (unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key);


The crypt.c is so defined:

#include "./crypt.h"

#include "Memory.h"


Key cryptographic functions


int My_encrypt_func (unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key)


return 0;



Key decryption functions


int My_deencrypt_func (unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key)


return 0;


This file is easy to see, just two functions, one for encryption and one for decryption. The parameters passed in are the data to be processed, the length of the data, the key, and the length of the key.

The result is processed directly to the content that the PData pointer points to.

You need to define your own encryption and decryption process, change these two functions, the other parts do not move. It's easy to expand.

Here is a feature that Data_len generally always 1024 bytes. Because of this, you can use some length-specific encryption algorithms in your algorithm, such as AES, which requires that the encrypted data must be 128 bits (16 bytes) long. This 1024 does not happen, but Sqlite's page definition is 1024 bytes, defined in the sqlite3.c file:

# define sqlite_default_page_size 1024x768

You can change the value, but it's not necessary to change it.

There are two extension functions written above, how to hook up the extension function with Sqlite, this process is more troublesome. I post the code directly.

3 steps.

First, at the top of the sqlite3.c file, add the following:


#include "./crypt.h"


Used to free some memory when the sqlite3 is last closed


void Sqlite3pager_free_codecarg (void *parg);


This function is declared at the beginning of the sqlite3.c because the function call is inserted in some of the functions below in sqlite3.c. So make a statement in advance.

Second, search for the "sqlite3pagerclose" function in the sqlite3.c file to find its implementation code (not the declaration code).

The implementation code begins with:

#ifdef sqlite_enable_memory_management

/* A malloc () cannot fail in Sqlite3threaddata () as one or more calls to

* * malloc () must has already been made by this thread before it gets

* * to the point. This means the threaddata must has been allocated already

* * So that threaddata.nalloc can set.


Threaddata *PTSD = Sqlite3threaddata ();

ASSERT (Ppager);

ASSERT (PTSD && ptsd->nalloc);


Needs to be inserted immediately after this section:


Sqlite3pager_free_codecarg (PPAGER->PCODECARG);


It is important to note that the Sqlite3pagerclose function is also about 3.3. The 17 version was renamed, the previous version is called "Sqlite3pager_close". So you search for "Sqlite3pagerclose" in the old version of SQLite code.

Similar to the "Sqlite3pager_get", "Sqlite3pager_unref", "Sqlite3pager_write", "Sqlite3pager_pagecount" and so on are the old version functions, they are in the Pager.h defined in the file. The new version of the corresponding function is defined in sqlite3.h (because both are merged into the sqlite3.c and sqlite3.h two files). So, if you are using the old version of SQLite, first look at the Pager.h file, these functions are not disappearing, nor new pop out, but the old version of the function renamed.

Finally, go to the sqlite3.c file. Find the last line:

/************** End of Main.c ************************************************/

After this line, follow the code snippet at the bottom of this article.

The code is very long, I don't explain it, just connect it up.

The only thing to mention is the Derivekey function. This function is an extension of the key. For example, you require that the key be 128 bits, which is 16 bytes, but what if the user only enters 1 bytes? What about 2 bytes? Or enter a 50 bytes? You have to extend the key to match the 16-byte requirement.

The Derivekey function is to do this extension. Someone MD5 the received key, which is also a method, because the result of the MD5 operation is fixed at 16 bytes, no matter how many characters you have, and finally 16 bytes. This is the feature of the MD5 algorithm. But I don't want to use MD5 because I have to add a. C or. cpp file that contains some MD5. I don't want to do this. I wrote an algorithm myself to extend the key, very simple algorithm. Of course, you can also use your extension method, and you can use the MD5 algorithm. As long as you modify the Derivekey function.

In the Derivekey function, just apply for the key that is required for the space construct and do not need to be freed because there is a release process in the other function, and that function is called when the database is closed. Refer to my Derivekey function to request memory.

Here I give the sqlite3.c and sqlite3.h files that I have modified.

If you are too lazy, you can use these two files directly, the compilation will pass, and the operation is normal. Of course, you have to create the new crypt.h and crypt.c files as I mentioned earlier, and the function should be done in accordance with the requirements I defined earlier.

I.3 How to use encryption:

Now, your code already has the encryption function.

You have to use the encryption function, in addition to changing the sqlite3.c file, to your project to add SQLITE_HAS_CODEC macros, but also to modify your database call function.

As mentioned earlier, to start a database operation, you must first Sqlite3_open.

The encryption and decryption process is done behind Sqlite3_open.

Assuming you have sqlite3_open success, write the following code immediately:

int i;

Add, use password

i = Sqlite3_key (db, "DCG", 3);

Change Password

i = Sqlite3_rekey (db, "DCG", 0);

Use the Sqlite3_key function to submit the password.

The 1th parameter is the sqlite3 * type variable, which represents a database opened with Sqlite3_open (or a new database).

The 2nd parameter is a key.

The 3rd parameter is the length of the key.

use Sqlite3_rekey to change the password. the parameters mean the same as Sqlite3_key.

In fact, after the Sqlite3_open function, you can call Sqlite3_key anywhere before the Sqlite3_close function to set the password.

But if you don't have a password, and the database has a password before it, you'll get a return value for any operation: Sqlite_notadb, and get an error message: "File is encrypted or was not a database".

Only if you set the correct password with Sqlite3_key, the database will work properly.

If you want to change the password, if you must first Sqlite3_open open the database successfully, and then Sqlite3_key set the key successfully, before you can use Sqlite3_rekey to modify the password.

If the database has a password, but you do not use Sqlite3_key to set the password, then when you try to use Sqlite3_rekey to modify the password, you will get SQLITE_NOTADB the return value.

If you need to clear your password, you can use:

Change Password

i = Sqlite3_rekey (db, NULL, 0);

To complete the password erase function.

i.4 sqlite3.c last Add code snippet


Dong Chun Optical definition of cryptographic functions




Cryptographic structure


#define CRYPT_OFFSET 8

typedef struct _CRYPTBLOCK


Byte* ReadKey; Read the database and write the transaction key

Byte* Writekey; Keys written to the database

int PageSize; Size of page

Byte* Data;

} Cryptblock, *lpcryptblock;

#ifndef db_key_length_byte/* Key length */

#define DB_KEY_LENGTH_BYTE 16/* Key length */


#ifndef db_key_padding * * The characters that are added when the key bit is insufficient */

#define DB_KEY_PADDING 0x33 * * The characters that are added when the key is insufficient




SQLite source code encryption, and some other articles

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.