How to Password Encrypt SQLite Database

Password Protect a SQLite DB. Is it possible?

You can password protect a SQLite3 DB. Before doing any operations, set the password as follows.

SQLiteConnection conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
conn.SetPassword("password");
conn.Open();

then next time you can access it like

conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;Password=password;");
conn.Open();

This wont allow any GUI editor to view your data. Some editors can decrypt the DB if you provide the password. The algorithm used is RSA.

Later if you wish to change the password, use

conn.ChangePassword("new_password");

To reset or remove password, use

conn.ChangePassword(String.Empty);

SQLite with encryption/password protection

SQLite has hooks built-in for encryption which are not used in the normal distribution, but here are a few implementations I know of:

  • SEE - The official implementation.
  • wxSQLite - A wxWidgets style C++ wrapper that also implements SQLite's encryption.
  • SQLCipher - Uses openSSL's libcrypto to implement.
  • SQLiteCrypt - Custom implementation, modified API.
  • botansqlite3 - botansqlite3 is an encryption codec for SQLite3 that can use any algorithms in Botan for encryption.
  • sqleet - another encryption implementation, using ChaCha20/Poly1305 primitives. Note that wxSQLite mentioned above can use this as a crypto provider.

The SEE and SQLiteCrypt require the purchase of a license.

Disclosure: I created botansqlite3.

System.Data.SQLite What Type/Level of Password Encryption is used

I took a look through the CHM documentation on the home page. It barely mentions the encryption. The only info I could find was in the version history, which says this:

1.0.24.3 beta - January 10, 2006


...

  • Added support for database encryption at the pager level. Databases are encrypted using a 128-bit RC4 stream algorithm. To open an existing encrypted database, you may now specify a "Password={password}" text in the ConnectionString, or you may call the SQLiteConnection.SetPassword() function to set the password on an open connection. To encrypt existing non-encrypted databases or to change the password on an encrypted database, you must use the SQLiteConnection.ChangePassword() function. If you use SetPassword() instead of specifying a password in the connection string, or call ChangePassword() you may use a binary byte array or a text string as the password.

...

(emphasis mine)

A quick glance at the RC4 Wikipedia Page reveals that "multiple vulnerabilities have been discovered in RC4, rendering it insecure." I wouldn't trust it.

Also worth noting: the encryption module you're talking about is not a feature of SQLite, but rather an extension that the System.Data.SQLite library provides. Using it will make your database inoperable with other SQLite readers.

Can i password encrypt SQLite database?

I use SQLite version 3 works perfectly!
You have to do that:

//if the database has already password
try{
string conn = @"Data Source=database.s3db;Password=Mypass;";
SQLiteConnection connection= new SQLiteConnection(conn);
connection.Open();
//Some code
connection.ChangePassword("Mypass");
connection.Close();
}
//if it is the first time sets the password in the database
catch
{
string conn = @"Data Source=database.s3db;";
SQLiteConnection connection= new SQLiteConnection(conn);
connection.Open();
//Some code
connection.ChangePassword("Mypass");
connection.Close();
}

thereafter if the user tries to open the database. will say protected by Admin or the database is encrypted or is not a database or corrupted file!

How encrypt SQLite database with FireDAC?

To encrypt a database, use a TFDSQLiteSecurity Component. You'll also need a TFDSQLitePhysSQLiteDriverLink component to go along with it.

If a database is unencrypted, then its password is ''. So use '' as the OldPassword and create the new password in that case. Passwords are formatted as algorithm:PassPhrase. See documentation on the choices, I use aes-256. Also, the database needs to be closed when you do this.

...
//Change password
FDSQLiteSecurity1.Password := OldPassword;
FDSQLiteSecurity1.ToPassword := NewPassword; // example: 'aes-256:mypassword123'
FDSQLiteSecurity1.ChangePassword;
...
//Remove Password
FDSQLiteSecurity1.Password := OldPassword;
FDSQLiteSecurity1.ToPassword := '';
FDSQLiteSecurity1.RemovePassword;
...

Sqlite connection string with encrypted password

Source of the issue

I assume that the actual reason for this error is the the lack of support in "legacy CryptoAPI" since System.Data.SQLite version ~1.0.113.1.

It was done in the following commit:
https://system.data.sqlite.org/index.html/info/1dd56c9fd59a10fd

What can we do?

  1. Manually Use the last NuGet version with CryptoAPI support - 1.0.112.2.

    Notice - It must be done manually - either by editing PackageReference in csproj or by editing config.packages.
    the reason is that older versions are unlisted (!) from the NuGet feed:
    NuGet feed only shows ONE version

  2. Buy perpetual source code license for SQLite Encryption Extension (SEE) which costs one time fee of 2000$ (as of Feb 2021) - purchase link

  3. Use SQLCipher - SQLCipher is an SQLite extension that provides 256 bit AES encryption of database files - GitHub source (haven't tested it myself!)

Data Sources

  • https://system.data.sqlite.org/index.html/tktview?name=9c330a3e03
  • https://stackoverflow.com/a/64392325/426315


Related Topics



Leave a reply



Submit