sqlite unable to open database file is encrypted or is not a database?
2Toad's answer is mostly correct, but I wanted to add my own because there are some clarifications to be made. As 2Toad said, this is correct:
When you specify a password in the connection string, and the database already exists, SQLite assumes the database is encrypted and will try to decrypt it with said password. If you haven't set a password on the database yet, this will result in the "file is encrypted" error, because the supplied password can't be used to decrypt an unencrypted database.
But this error can also happen if you try to use conn.SetPassword("something")
after you already had another one in the connection string. Or if you do conn.ChangePassword("somethingelse")
, but still have Password=something
in the connection string.
There are several scenarios to consider:
- The database has had a password applied, and it is in the connection string.
- You have a password in the connection string, but the database does not have one applied, or the password in the string does not match the DB.
- The database has never had a password, and you want to change it.
- The database has had a password, and you want to change it.
Resolutions:
So the code 2Toad provided to perform
conn.ChangePassword("somethingelse")
is only half-correct and doesn't take into account where you are, what else you've done, and what you want to do in the future. If you have an existing password and you want to change it, this is correct, but you also have to be sure the connection string is updated afterwards, or subsequent connections will fail with thefile is encrypted
error.This scenario happens if you blank the password using
conn.SetPassword("")
and then tryconn.ChangePassword("somethingelse")
without first connecting to the database without thePassword=something
in the connection string. ThatPassword=something
would have to be removed from the connection string, because the password has been removed programmatically from the DB and the DB will try connecting with that. If it's not removed from the connection string at the same time as it's removed from the DB programmatically, you'll get the samefile is encrypted
error.Because I started out by doing a
conn.SetPassword("something")
in the very beginning when I didn't have a password applied (and I believe this is the way to do that), I cannot verify the following without creating another SQLite DB, but I do not believe you can callconn.ChangePassword("something")
if you never had a password in the first place. You should doconn.SetPassword("something")
for the initial set, and then putPassword=something
in your connection string.The way I did a change of a password was where I did
conn.ChangePassword("somethingelse")
only after doingconn.SetPassword("")
and clearing thePassword=something
from the connection string:// Changes an encrypted database to unencrypted and removes password string connString = "Data Source=c:\\test.db3;Password=something"; SQLiteConnection conn = new SQLiteConnection(connString); conn.SetPassword(""); //conn.Open(); // doesn't work because connString hasn't been updated // Update connString connString = "Data Source=c:\\test.db3;"; conn = new SQLiteConnection(connString); conn.Open(); // we've opened the DB without a password // Re-encrypts the database. The connection remains valid and usable afterwards until closed - then the connection string needs updating. conn.ChangePassword("somethingelse"); conn.Close(); // Update connString connString = "Data Source=c:\\test.db3;Password=somethingelse"; conn = new SQLiteConnection(connString); // must re-instantiate! conn.Open(); // we've opened the DB with our new password
This worked out fine. I suppose you can also not clear it from the connection string and simply do conn.ChangePassword("somethingelse")
, and then add Password=somethingelse
to your string, afterwards:
// Opens an encrypted database
string connString = "Data Source=c:\\test.db3;Password=something";
SQLiteConnection conn = new SQLiteConnection(connString);
conn.Open();
// Encrypts the database. The connection remains valid and usable afterwards until closed - then the connection string needs updating.
conn.ChangePassword("somethingelse");
conn.Close();
// Update connString
connString = "Data Source=c:\\test.db3;Password=somethingelse";
conn = new SQLiteConnection(connString);
conn.Open(); // we've opened the DB with our new password
Personally, I store the password as encrypted in an app (web) .config file, and call it into a variable in my application onload and dynamically build my connection string from it.
That I know of, if you delete a SQLite DB and try to call it, you will simply get an error - not a re-created SQLite DB with a new password from your connection string - at least when using and calling it from a C# .NET app.
UPDATE If you need a function that will be used for updating the password after you already have one, you don't want to have .SetPassword()
, but .ChangePassword()
. I found it is also better to always blank it out, then change it, like in my first example in #4.
When you specify a password in the connection string, and the database already exists, SQLite assumes the database is encrypted and will try to decrypt it with said password. If you haven't set a password on the database yet, this will result in the "file is encrypted" error, because the supplied password can't be used to decrypt an unencrypted database.
You can either delete the database, and SQLite will create a new encrypted database using the password in the connection string. Or, you can encrypt your existing database using the ChangePassword()
method:
// 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");
Reference: Encrypting, decrypting and attaching to encrypted databases