17

我正在使用 sqlite 数据库开发 Windows 应用程序 .net 2.0,我的连接字符串保留在 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,正如我在连接字符串中所述,我也尝试删除“版本 = 3”,但问题仍然存在。

我是第一次这样做,有什么解决办法吗?

4

3 回答 3

14

当您在连接字符串中指定密码并且数据库已经存在时,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");

参考:加密、解密和附加到加密数据库

于 2013-04-16T07:41:18.283 回答
4

2Toad 的回答大部分是正确的,但我想添加自己的答案,因为需要进行一些澄清。正如 2Toad 所说,这是正确的:

当您在连接字符串中指定密码并且数据库已经存在时,SQLite 假定数据库已加密并尝试使用所述密码对其进行解密。如果您尚未在数据库上设置密码,这将导致“文件已加密”错误,因为提供的密码不能用于解密未加密的数据库。

conn.SetPassword("something")但是,如果您在连接字符串中已有另一个之后尝试使用,也会发生此错误。或者,如果您这样做conn.ChangePassword("somethingelse"),但仍然Password=something在连接字符串中。

有几种情况需要考虑:

  1. 数据库已应用密码,并且在连接字符串中。
  2. 您在连接字符串中有密码,但数据库没有应用密码,或者字符串中的密码与数据库不匹配。
  3. 数据库从未有过密码,而您想更改它。
  4. 数据库有密码,您想更改它。

决议:

  1. 所以 2Toad 提供的执行代码conn.ChangePassword("somethingelse")只有一半正确,并且没有考虑到你在哪里,你还做了什么,以及你将来想做什么。如果您有一个现有的密码并且想要更改它,这是正确的,但您还必须确保之后更新连接字符串,否则后续连接将失败并出现file is encrypted错误。

  2. 如果您使用空白密码conn.SetPassword("")然后尝试在没有连接字符串conn.ChangePassword("somethingelse")的情况下先连接到数据库,则会发生这种情况。Password=somethingPassword=something必须从连接字符串中删除,因为密码已从数据库中以编程方式删除,并且数据库将尝试与之连接。如果它没有在以编程方式从数据库中删除的同时从连接字符串中删除,您将收到相同的file is encrypted错误。

  3. 因为我一开始conn.SetPassword("something")就在没有应用密码的时候做了 a (我相信这是这样做的方法),所以如果不创建另一个 SQLite DB,我无法验证以下内容,但我不相信你conn.ChangePassword("something")如果您一开始就没有密码,可以打电话。您应该conn.SetPassword("something")为初始设置做,然后放入Password=something您的连接字符串。

  4. 我更改密码的方式是我在完成并从连接字符串中清除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 - 至少在使用和调用它时从 C# .NET 应用程序。

更新如果您需要一个在您已经拥有密码后用于更新密码的功能,您不想拥有.SetPassword(), 但是.ChangePassword(). 我发现最好总是把它清空,然后改变它,就像我在#4中的第一个例子一样。

于 2017-05-03T21:45:11.063 回答
1

检查 SQLite 的版本。有些数据库只能通过 sqlite3 打开。

于 2020-11-22T21:22:56.203 回答