110

I have to face a new little project. It will have about 7 or 9 tables, the biggest of them will grow by a max rate of 1000 rows a month.

I thought about SQLite as my db... But i will need to protect the db in case anybody wants to change data from the db

My main question is:

Is it possible password protect a sqlite db as you would do on access?

The development would be on C#, but I'm searching something free.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Jhonny D. Cano -Leftware-
  • 17,663
  • 14
  • 81
  • 103
  • 1
    http://stackoverflow.com/questions/5669905/sqlite-with-encryption-password-protection/5877130#5877130 – OliJG May 04 '11 at 00:14
  • 3
    You might want to check out [SQLiteCrypt](http://sqlite-crypt.com/index.htm) – Mike Buckbee Sep 04 '09 at 20:11
  • If you need to lock/unlock DB frequently for debugging, try this tool http://goo.gl/12VnQd – Mangesh Apr 03 '15 at 04:55
  • You can find the solution here [enter link description here](http://stackoverflow.com/questions/4678237/how-can-i-password-protect-my-sqlite-db-in-c-is-it-possible-to-partition-the-sq/40763590#40763590) – Ishwar Rimal Nov 23 '16 at 11:46
  • Possible duplicate of [SQLite with encryption/password protection](https://stackoverflow.com/questions/5669905/sqlite-with-encryption-password-protection) – iammilind Oct 17 '19 at 03:29

8 Answers8

87

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);
Fortis
  • 43
  • 2
  • 8
Mangesh
  • 5,491
  • 5
  • 48
  • 71
  • The only free tool I have found so far that will open password protected databases like this is [SQLite2009 Pro](http://sqlite2009pro.azurewebsites.net/) detailed in [this answer](http://stackoverflow.com/a/12624529/345659). – JumpingJezza Jul 10 '15 at 01:53
  • What lang is this example? Looks like .NET? – pim Dec 27 '15 at 14:48
  • 2
    Technically, .NET is framework. C# is the language being displayed here. – vapcguy May 02 '17 at 19:23
  • Also, you have to be careful with updating the connection string prior to the next opening each time you change the password or you can end up facing errors: http://stackoverflow.com/questions/16030601/sqlite-unable-to-open-database-file-is-encrypted-or-is-not-a-database – vapcguy May 03 '17 at 22:28
  • 2
    Remark that, with no password provided, Open() will NOT fail on a password-protected SQLite database, as you would expect! What fails is any subsequent data or metadata operation on that open file. – Cristian Scutaru Jun 16 '18 at 12:46
  • 1
    Strangely, this code doesn't work in VB.Net. I get an error saying both SetPassword and ChangePassword are not members of SQLiteConnection – user3267567 Oct 24 '20 at 20:06
  • method .SetPassword is not supported for free System.Data.SQLite.dll... – qtg Sep 25 '21 at 01:31
  • System.Data.SQLite.Core version 1.0.112 or lower does support the ".SetPassword()" function. However, this functionality was removed there after. – Nandostyle Aug 15 '23 at 17:56
34

You can use the built-in encryption of the sqlite .net provider (System.Data.SQLite). See more details at http://web.archive.org/web/20070813071554/http://sqlite.phxsoftware.com/forums/t/130.aspx

To encrypt an existing unencrypted database, or to change the password of an encrypted database, open the database and then use the ChangePassword() function of SQLiteConnection:

// Opens an unencrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
// Encrypts the database. The connection remains valid and usable afterwards.
cnn.ChangePassword("mypassword");

To decrypt an existing encrypted database call ChangePassword() with a NULL or "" password:

// Opens an encrypted database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3;Password=mypassword");
cnn.Open();
// Removes the encryption on an encrypted database.
cnn.ChangePassword(null);

To open an existing encrypted database, or to create a new encrypted database, specify a password in the ConnectionString as shown in the previous example, or call the SetPassword() function before opening a new SQLiteConnection. Passwords specified in the ConnectionString must be cleartext, but passwords supplied in the SetPassword() function may be binary byte arrays.

// Opens an encrypted database by calling SetPassword()
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.SetPassword(new byte[] { 0xFF, 0xEE, 0xDD, 0x10, 0x20, 0x30 });
cnn.Open();
// The connection is now usable

By default, the ATTACH keyword will use the same encryption key as the main database when attaching another database file to an existing connection. To change this behavior, you use the KEY modifier as follows:

If you are attaching an encrypted database using a cleartext password:

// Attach to a database using a different key than the main database
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY 'mypassword'", cnn);
cmd.ExecuteNonQuery();

To attach an encrypted database using a binary password:

// Attach to a database encrypted with a binary key
SQLiteConnection cnn = new SQLiteConnection("Data Source=c:\\test.db3");
cnn.Open();
cmd = new SQLiteCommand("ATTACH DATABASE 'c:\\pwd.db3' AS [Protected] KEY X'FFEEDD102030'", cnn);
cmd.ExecuteNonQuery();
Hanlet Escaño
  • 17,114
  • 8
  • 52
  • 75
Liron Levi
  • 1,139
  • 6
  • 10
  • 2
    This link-only-answer is in fact a clear example why we don't do link-only answers at SO. The actual link is gone; it doesn't exist anymore. The only reason we are able to see the site is because it was automatically archived by web.archive.org. – Hanlet Escaño Dec 14 '17 at 16:24
  • It does not work anymore , no such functions found in the latest versions. – MindRoasterMir Aug 01 '20 at 16:22
  • “You can use the built-in encryption of the sqlite .net provider (System.Data.SQLite)” I’m not sure what is meant by “built-in.” One still needs a $2000 license for the SQLite Encryption Extension to use the `SetPassword()` or `ChangePassword()` methods of System.Data.SQLite…right? – RonC Jan 27 '23 at 13:47
16

Use SQLCipher, it's an opensource extension for SQLite that provides transparent 256-bit AES encryption of database files. http://sqlcipher.net

Community
  • 1
  • 1
Avdaff
  • 161
  • 1
  • 2
  • 2
    How about speed? If i use sqlcipher will it reduce the performance? – TomSawyer Jun 08 '16 at 09:44
  • Any robust solution for this case will be based on symmetric encryption algo even in the case of RSA. RSA (previously mentioned) will only be used to encrypt the key for the symmetric algo and not encrypt anything with RSA. AES256 is a very performant symmetric algo and one of the highest secure one. Use it directly seems to be good choice. be careful for the key ! – Mohamed Hamzaoui Jun 30 '21 at 10:01
7

You can encrypt your SQLite database with the SEE addon. This way you prevent unauthorized access/modification.

Quoting SQLite documentation:

The SQLite Encryption Extension (SEE) is an enhanced version of SQLite that encrypts database files using 128-bit or 256-Bit AES to help prevent unauthorized access or modification. The entire database file is encrypted so that to an outside observer, the database file appears to contain white noise. There is nothing that identifies the file as an SQLite database.

You can find more info about this addon in this link.

rogeriopvl
  • 51,659
  • 8
  • 55
  • 58
3

If you use FluentNHibernate you can use following configuration code:

private ISessionFactory createSessionFactory()
{
    return Fluently.Configure()
            .Database(SQLiteConfiguration.Standard.UsingFileWithPassword(filename, password))
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DBManager>())
            .ExposeConfiguration(this.buildSchema)
            .BuildSessionFactory();    
}

private void buildSchema(Configuration config)
{
        if (filename_not_exists == true)
        {
            new SchemaExport(config).Create(false, true);
        }
}    

Method UsingFileWithPassword(filename, password) encrypts a database file and sets password.
It runs only if the new database file is created. The old one not encrypted fails when is opened with this method.

Bronek
  • 10,722
  • 2
  • 45
  • 46
3

One option would be VistaDB. They allow databases (or even tables) to be password protected (and optionally encrypted).

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 2
    There are more efficient and free ways! – Saw Jun 17 '12 at 08:02
  • 1
    @MSS But - as I said, the VistaDB solution does have some advantages, including separate encryption on a table level instead of full DB connection encryption. I know of no other .NET native option that accomplishes this. It's also pure managed, unlike most other options - just because it's not free doesn't mean that there are more efficient or better options - it depends completely on the usage requirements. – Reed Copsey Jun 18 '12 at 15:21
2

I know this is an old question but wouldn't the simple solution be to just protect the file at the OS level? Just prevent the users from accessing the file and then they shouldn't be able to touch it. This is just a guess and I'm not sure if this is an ideal solution.

David Price
  • 170
  • 1
  • 16
  • 2
    I'm not sure if that's a good solution because anyone with a USB stick could boot into another OS and read the files. – nurettin Apr 08 '16 at 22:10
  • I think that is fair point out, but then in that case disable the USB. If some has physical access to your machine there are a lot of other things that can be done. – David Price Apr 10 '16 at 05:13
  • You want to protect sensitive data so that *only* those other things will go wrong. – tripleee May 03 '16 at 05:07
  • With the SQLite database, this is actually NOT possible at all. You need users to be able to both read AND write to it, meaning the ACL of the folder where the SQLite DB lives has to allow them those permissions, too. You can secure it against non-users by only allowing the real users permission to that folder, but you still have the "insider threat". – vapcguy May 02 '17 at 21:35
0

Why do you need to encrypt the database? The user could easily disassemble your program and figure out the key. If you're encrypting it for network transfer, then consider using PGP instead of squeezing an encryption layer into a database layer.

  • 9
    User could be asked for password at start up so no key would be achievable by disassembling the program. – kgadek Jun 02 '12 at 18:04
  • 1
    Use Redgate Reflector, or ILSpy. – Zev Spitz Sep 09 '13 at 05:56
  • 5
    Why would you put the key into the program? you wouldn't do that, generate a key from the users password and use that, then you dont need any secrets in your source code. – trampster Sep 27 '13 at 04:08