繁体   English   中英

sqlite无法打开数据库文件是加密的还是不是数据库?

[英]sqlite unable to open database file is encrypted or is not a database?

我正在使用带有 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”,但问题仍然存在。

我是第一次这样做,它的解决方案是什么?

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

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

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

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

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

有几种情况需要考虑:

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

决议:

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

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

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

  4. 我更改密码的方式是在执行conn.SetPassword("")并从连接字符串中清除Password=something之后才执行conn.SetPassword("") conn.ChangePassword("somethingelse")

     // 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 中的第一个示例一样。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM