Sqlite не может открыть файл базы данных зашифрован или не является базой данных?
Я работаю над приложением Windows.net 2.0 с базой данных sqlite, моя строка подключения остается в app.config вроде
<connectionStrings>
<add name="SQLiteDB"
connectionString="Data Source=|DataDirectory|database.s3db;version=3;password=mypassword;"
providerName="System.Data.Sqlite"/>
</connectionStrings>
В строке подключения я определил пароль как "mypassword", если я удалю этот пароль, все работает хорошо, но когда я использую предложение пароля, это дает мне ошибку в синтаксисе connection.open(), который
File opened that is not a database file
file is encrypted or is not a database
Я искал в сети и обнаружил некоторую проблему с версией, но я использую версию 3 только в том виде, в каком я указал в строке подключения, я также попытался удалить "version = 3", но проблема осталась прежней.
Я делаю это в первый раз, каково его решение?
Ответы
Ответ 1
Когда вы укажете пароль в строке подключения и база данных уже существует, SQLite предполагает, что база данных зашифрована и будет пытаться расшифровать ее с помощью указанного пароля. Если вы еще не установили пароль в базе данных, это приведет к ошибке "файл зашифрован", поскольку предоставленный пароль не может использоваться для дешифрования незашифрованной базы данных.
Вы можете либо удалить базу данных, и SQLite создаст новую зашифрованную базу данных, используя пароль в строке подключения. Или вы можете зашифровать существующую базу данных с помощью метода ChangePassword()
:
// 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");
Ссылка: Шифрование, дешифрование и прикрепление к зашифрованным базам данных
Ответ 2
2 Ответ на загрузку в основном правильный, но я хотел добавить свое, потому что есть некоторые пояснения. Как сказал 2Toad, это правильно:
Когда вы укажете пароль в строке подключения и база данных уже существует, SQLite предполагает, что база данных зашифрована и попытается расшифровать ее с помощью указанного пароля. Если вы еще не установили пароль в базе данных, это приведет к ошибке "файл зашифрован", поскольку предоставленный пароль не может использоваться для дешифрования незашифрованной базы данных.
Но эта ошибка также может произойти, если вы попытаетесь использовать conn.SetPassword("something")
после того, как у вас уже есть другой в строке подключения. Или, если вы выполняете conn.ChangePassword("somethingelse")
, но все еще имеете Password=something
в строке соединения.
Существует несколько сценариев:
- В базе данных был применен пароль, и он находится в строке подключения.
- У вас есть пароль в строке подключения, но в базе данных нет ни одного приложения, либо пароль в строке не соответствует БД.
- В базе данных никогда не было пароля, и вы хотите изменить его.
- В базе данных есть пароль, и вы хотите изменить его.
Решения:
-
Таким образом, код 2Toad, предоставленный для выполнения conn.ChangePassword("somethingelse")
, является только неполным и не учитывает, где вы находитесь, что еще вы сделали и что вы хотите делать в будущем. Если у вас есть существующий пароль, и вы хотите его изменить, это правильно, но вы также должны быть уверены, что строка подключения будет обновлена впоследствии или последующие подключения не будут выполнены с ошибкой file is encrypted
.
-
Этот сценарий происходит, если вы очистите пароль с помощью conn.SetPassword("")
, а затем попробуйте conn.ChangePassword("somethingelse")
без первого подключения к базе данных без Password=something
в строке подключения. То, что Password=something
должно быть удалено из строки подключения, поскольку пароль был удален программно из БД, и БД попытается соединиться с этим. Если он не удаляется из строки подключения одновременно с удаленным из БД программным способом, вы получите ту же ошибку file is encrypted
.
-
Поскольку я начал с conn.SetPassword("something")
в самом начале, когда у меня не было введенного пароля (и я считаю, что это способ сделать это), я не могу проверить следующее, не создавая другого SQLite DB, но я не думаю, что вы можете позвонить conn.ChangePassword("something")
, если у вас никогда не было пароля. Вы должны сделать conn.SetPassword("something")
для исходного набора, а затем поместите Password=something
в строку подключения.
-
Как я сменил пароль, я сделал conn.ChangePassword("somethingelse")
только после выполнения conn.SetPassword("")
и очистки Password=something
от строки подключения:
// 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
Это получилось отлично. Я полагаю, вы также можете не очистить его от строки подключения и просто сделать conn.ChangePassword("somethingelse")
, а затем добавить Password=somethingelse
в свою строку, а затем:
// 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
Лично я сохраняю пароль как зашифрованный в файле приложения (web).config и вызываю его в переменную в моем приложении onload и динамически строю из нее строку подключения.
Что я знаю, если вы удалите SQLite DB и попытаетесь вызвать его, вы просто получите сообщение об ошибке - а не заново созданный SQLite DB с новым паролем из вашей строки подключения - по крайней мере, при использовании и вызове из приложения С#.NET.
UPDATE Если вам нужна функция, которая будет использоваться для обновления пароля после его наличия, вы не хотите иметь .SetPassword()
, но .ChangePassword()
. Я обнаружил, что лучше также всегда его исключить, а затем изменить, как в моем первом примере в # 4.