How does anyone start with sqlicipher at windows and c++?

Hello sqlciphers, i manage somehow to build the sqlcipher and i got the sqlcipher32.lib and the sqlcipher-shell32.exe.

I was having a ready sqlite3 simple application that was creating a database, a table and some functions in it with sqlite3 and i don`t know how am i suppose to use sqlichiper inside this application and check if it is working as it should.

As first attemp i just added the sqlcipher32.lib to my project and used the PRAGMA key=‘testcode’ but the database that was created was not encrypted.
I added also the code #define SQLITE_HAS_CODEC but nothing happened too.

I want to implement the sqlcipher in a c++ mvs2013 project.

Can anyone point me where and how to start using it as a total noob i am ?

Thank you in advance

Hi @Nocs

Congratulations on building the library. The simplest way to verify the library was built properly is to run the SQLCipher shell program and execute the following SQL statement within the prompt:

sqlcipher-shell32.exe
sqlite> PRAGMA cipher_version;

This command will report back the SQLCipher version compiled into the library. Next, you can use the SQLCipher shell program to create an encrypted database. An example:

sqlcipher-shell32.exe test.db
sqlite> PRAGMA key = 'test';
sqlite> CREATE TABLE t1(alb);
sqlite> INSERT INTO t1(a,b) VALUES ('one for the money', 'two for the show');
sqlite> .q

Next, you will want to verify the raw content of the test.db file, making sure you do not see plain text, but rather random data. You can utilize a tool such as hexdump to do this, here is a link to a build for Windows.

hexdump -C test.db

If either you don’t see a version number printed above, or the raw hex dump of the database is in plain text, your library was not likely built properly.

I confirm that sqlcipher is a marvelous encrypter for sqlite database :smiley: and congruts to all developers.
It is working perfect but now to make my question more detailed since it is working with the sqlcipher-shell

I want to be able to use sqlcipher inside a c++ application and be able to create, encrypt, decrypt and use the database from my applciation like sqlite i was using till now but with sqlcipher now it will be also encrypted with a key.

How can i use the sqlcipher32.lib and the sqlcipher-shell32.exe inside my c++ project ?
Do i need any headers cause that is where my question was pointing.
I can`t compile it inside a c++ program.
And also does that implementation way changes anything on the license issues ?

Hello @Nocs - There are a few options here. One option is to link your C++ program against a static sqlcipher lib you generated. The second option would be to make the SQLCipher DLL, and then use that in your program. The final option would be to jut include the amalgamation (i.e. sqlcipher.c / sqlite3.c) into your program. In all of those cases you’ll need to include the sqlite3.h header file from the SQLCipher distribution.

Thanks for the respond sjlombardo,
I have tried everything but it doesn`t want to compile inside a c++ project, i am sure there is an error in the headers since the sqlcipher32.lib is static.

Here is a link that i used to compile the static lib and shell for windows and it is working perfect but only from the shell.exe Sqlcipher for windows

Since i am not so experienced in c++ and compiliations in mvs and windows, maby someone could give a hand and tell me what headers or what should i do to make the sqlcipher32.lib work inside a c++ project.
Also a guidance on this would be great for many others who want to use this marvelous sqlcipher but are not so experienced in c++ and complicated compilations.
There are also ready precompiled for all versions libs and headers of openssl versions and if anyone want and has problems compiling them i can provide the helpfull link

Thanks in advance

I have also tried this compilation of sqlcipher http://www.jerryrw.com/howtocompile.php but it doesnt work for me and i dont know why.

it gives errors on the most basic for me : "make sqlite3.c"
It says that the tclsh function cant be found so it doesn`t export the sqlite3.c though in the function i use the option not to use the tcl …
I tried with some different versions of sqlcipher but it has the same error.

I would prefer the static lib build in my previous post but the problem is that none of the headers of sqlcipher with that static lib is working, it needs whatever i do the cyrpto.c though i used every crypto header and .c files from the sqlcipher amalgamation that is used to build the static lib

Is there anyone that can help around this issue ?

Anyone who knows how to compile in win32 application in mvs the sqlcipher ?

The build of the static lib is very easy but i cant use it in any project of mvs cause is asking always for the crypto.c file though i use it from the amalgamation of the below link.
Sqlcipher for windows

Here are also precompiled ready openssl libs and headers in many versions.
Precompiled openssl

Can anyone try use this static lib produced by the above link in a c++ win32 mvs project and give a tip on it how to compile it correct ?

Hi @Nocs

Can you post the specific error and build output you receive when trying to use the library you built?

I write all details below :

  • Header Files in project
    crypto.h
    sqlite3.h

  • Source Files in project
    crypto.c
    source.cpp
    sqlite3.c

  • Project Files DIrectory
    crypto.c
    crypto.h
    crypto_cc.c
    crypto_impl.c
    crypto_libtomcrypt.c
    crypto_openssl.c
    sqlite3.c
    sqlite3.h
    sqlcipher32.lib
    Source.cpp

  • Code



    #include “sqlite3.h”

#pragma comment(lib, “sqlcipher32.lib”)

  • Error

1>------ Rebuild All started: Project: ConsoleApplication4, Configuration: Release Win32 ------
1> crypto.c
1> sqlite3.c
1>sqlite3.c(141412): fatal error C1083: Cannot open include file: ‘crypto.c’: No such file or directory
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

The .h and .c files i use are from the sqlcipher for windows that created the sqlcipher32.lib

Hello @Nocs - if you have already built a static sqlcipher library, you should not need to include any of those files. The only think you’d need to include is sqlite3.h.

Yes thats what i know till now by other project build with static lib.
But again if i use only the sqlite3.h and sqlite3.c files from the build of the static lib project by just copying them to my new project it has again the same error.

1>------ Rebuild All started: Project: ConsoleApplication4, Configuration: Release Win32 ------
1> sqlite3.c
1>sqlite3.c(141412): fatal error C1083: Cannot open include file: ‘crypto.c’: No such file or directory
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

I think that the sqlite3.h and sqlite3.c must be created somehow from the project that builds the static lib
but i really don`t know how to do it.
In the sqlite3.c that is needed and i use it in my new project in the end of this file it has these lines.

/******** BEGIN SQLCIPHER-WINDOWS /
#include <crypto.c>
#include <crypto_cc.c>
#include <crypto_impl.c>
#include <crypto_libtomcrypt.c>
#include <crypto_openssl.c>
/
END SQLCIPHER-WINDOWS **********/
i use them all of them in the previous example post and cant bypass this error.
I have removed these lines and try to build but is has many unresolved externals so it doesn`t compile.

Any idea how to get a new sqlite3.c without the need of the crypto.c since i suppose it is in the static lib.

Hello @Nocs

Since you have already built the static library, you can remove the references to sqlite3.c and crypto.c from within your application. As @sjlombardo mentioned, you can just reference the library and sqlite3.h.

I have tried evey possible solution thats why i open the post.
The sqlcipher lib is working fine as exported but only by using the shell.exe exported too.
If i use the exported lib which is static inside other c++ application with any header or any file from sqlcipher at least in windows 7 with mvs2013 i have unresolved errors and doesn`t compile or it is asking for more header and files and even if i use all the header and files it still need the same files which are inside the folders application :frowning: it is a bit of weird to me but i am not so experience to find out how to be able to overpass it and use sql lib inside my applicaiton cause i really needed.

Could possible anyone build the sqlite3.h and sqlite3.c from the version of 3.0.1 and send me the files cause somehow this files i have can be used as it seems only to build the static lib.
If i use only the sqlite3.h of sqlcipher i have unresolved externals in every function i use e.x. open database etc. etc.

Hi @Nocs

Can you share these errors? We would need to see this in order to provide assistance.

Is this project for commercial work, or personal?

The errors of unresolved are there when i dont use the sqlite3.c file and i use only the sqlite3.h so it is obvious that none function of the sqlite3.h without the sqlite3.c can be used inside any project.
The other errors about headers missing are posted above.

About the license i asked it also from my first post.
For the time being the application is just personal.
After all done it will go public and i don`t know if this is commercial or not but it will be free and closed code application even when it goes to public so anyone can use it too.
Is that affecting the license ? And what kind of license do i need for it ?

Hi @Nocs

Please post the specific errors you receive when you try to compile an application that links the static library you built and sqlite3.h.

You are welcome to use the community edition of SQLCipher core within your application. You must disclose both the SQLCipher license, and any corresponding dependent library licenses. We identify the licenses here for your reference.

I am glad about the license that can be used and thanks in advance.

Here i provide the code i found working and i use it inside my source.cpp file
The sqlite3.h i got it as is from the project that builds the sqlcipher32.lib not exported but as the project uses it to create the lib.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “sqlite3.h”

#pragma comment(lib, “sqlcipher32.lib”)

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for (i = 0; i<argc; i++){
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : “NULL”);
}
printf("\n");
return 0;
}

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

int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char sql;
char sqlCommand[400];
const char
data = “Callback function called”;

/* Open database */
rc = sqlite3_open("test.db", &db);
if (rc){
	fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
	exit(0);
}
else{
	fprintf(stdout, "Opened database successfully\n");
}

/* Encrypt database */
rc = sqlite3_key(db, "1q2w3e4r", 8);
if (rc){
	fprintf(stderr, "Can't encrypt database: %s\n", sqlite3_errmsg(db));
	exit(0);
}
else{
	fprintf(stdout, "Database encrypted successfully\n");
}

/* Create SQL statement */
sql = "CREATE TABLE COMPANY("  \
	"ID INT PRIMARY KEY     NOT NULL," \
	"NAME           TEXT    NOT NULL," \
	"AGE            INT     NOT NULL," \
	"ADDRESS        CHAR(50)," \
	"SALARY         REAL );";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if (rc != SQLITE_OK){
	fprintf(stderr, "SQL error: %s\n", zErrMsg);
	sqlite3_free(zErrMsg);
}
else{
	fprintf(stdout, "Table created successfully\n");
}

sprintf(sqlCommand, \
	"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "\
	"VALUES (%d,'%s',%d,'%s',%.2lf); "\
	"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "\
	"VALUES (%d,'%s',%d,'%s',%.2lf); "\
	"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "\
	"VALUES (%d,'%s',%d,'%s',%.2lf); "\
	"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "\
	"VALUES (%d,'%s',%d,'%s',%.2lf); "\
	, 1, "Paul", 32, "California", 20000.00
	, 2, "Allen", 25, "Texas", 15000.00
	, 3, "Teddy", 23, "Norway", 20000.00
	, 4, "Mark", 25, "Rich-Mond", 65000.00);

/* Create SQL statement */
/*
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
*/
/* Execute SQL statement */
rc = sqlite3_exec(db, sqlCommand, callback, 0, &zErrMsg);
if (rc != SQLITE_OK){
	fprintf(stderr, "SQL error: %s\n", zErrMsg);
	sqlite3_free(zErrMsg);
}
else{
	fprintf(stdout, "Records created successfully\n");
}

/* Create SQL statement */
sql = "SELECT * from COMPANY";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK){
	fprintf(stderr, "SQL error: %s\n", zErrMsg);
	sqlite3_free(zErrMsg);
}
else{
	fprintf(stdout, "Operation done successfully\n");
}

/* Create merged SQL statement */
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
	"SELECT * from COMPANY";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK){
	fprintf(stderr, "SQL error: %s\n", zErrMsg);
	sqlite3_free(zErrMsg);
}
else{
	fprintf(stdout, "Operation done successfully\n");
}

/* Create merged SQL statement */
sql = "DELETE from COMPANY where ID=2; " \
	"SELECT * from COMPANY";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK){
	fprintf(stderr, "SQL error: %s\n", zErrMsg);
	sqlite3_free(zErrMsg);
}
else{
	fprintf(stdout, "Operation done successfully\n");
}

sqlite3_close(db);
return 0;

}


And here are the errors

1>------ Rebuild All started: Project: ConsoleApplication4, Configuration: Release Win32 ------
1> Source.cpp
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _HMAC_Final
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _RAND_add
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_iv_length
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_sha1
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _HMAC_CTX_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _HMAC_CTX_init
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_CTX_set_padding
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_key_length
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _OPENSSL_add_all_algorithms_noconf
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _HMAC_Update
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CipherInit
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _RAND_bytes
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CipherFinal
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_block_size
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_MD_size
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CipherUpdate
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_CTX_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _PKCS5_PBKDF2_HMAC_SHA1
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_get_cipherbyname
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _EVP_CIPHER_nid
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _HMAC_Init_ex
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol _OBJ_nid2sn
1>D:\SQLite_Enc_Tests\Release\ConsoleApplication4.exe : fatal error LNK1120: 23 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

If i also use the sqlite3.c inside my program these unresolved externals will not exist and instead of it
it will ask me for new headers each time and after using all the headers it will search for crypto.c always
as mentioned in previous posts.

And here are the errors

1>------ Rebuild All started: Project: ConsoleApplication4, Configuration:
Release Win32 ------
1> Source.cpp
1>LINK : warning LNK4098: defaultlib ‘LIBCMT’ conflicts with use of other
libs; use /NODEFAULTLIB:library
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_HMAC_Final
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_RAND_add
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_iv_length
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_sha1
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_HMAC_CTX_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_HMAC_CTX_init
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_CTX_set_padding
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_key_length
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_OPENSSL_add_all_algorithms_noconf
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_HMAC_Update
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CipherInit
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_RAND_bytes
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CipherFinal
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_block_size
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_MD_size
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CipherUpdate
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_CTX_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_PKCS5_PBKDF2_HMAC_SHA1
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_get_cipherbyname
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_cleanup
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_EVP_CIPHER_nid
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_HMAC_Init_ex
1>sqlcipher32.lib(sqlite3.obj) : error LNK2001: unresolved external symbol
_OBJ_nid2sn
1>D:\SQLite_Enc_Tests\Release\ConsoleApplication4.exe : fatal error
LNK1120: 23 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Those errors indicate that you are missing the OpenSSL dependency.

Indeeeeeeeeeeeeeeeeeed ^.^
It was the only thing i didnt try cause since it was running from the shell without the need of openssl it didnt cross my mind that this could be an error from missing openssl static lib.

I just added the openssl static ilb and is all fine.
It solved the errors and builded and works as a charm :smile:
Thanks for your time and sorry about it cause in compilation issues i am still a big noob in c++

Thank you

I wish this would be better documented somewhere