簡體   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