2013-04-16 43 views
11

tôi đang làm việc trên một ứng dụng cửa sổ .net 2.0 với cơ sở dữ liệu SQLite, chuỗi kết nối của tôi nằm trong app.config nhưsqlite không thể mở tệp cơ sở dữ liệu được mã hóa hoặc không phải là cơ sở dữ liệu?

<connectionStrings> 
<add name="SQLiteDB" 
    connectionString="Data Source=|DataDirectory|database.s3db;version=3;password=mypassword;" 
    providerName="System.Data.Sqlite"/> 
</connectionStrings> 

Trong chuỗi kết nối tôi đã xác định mật khẩu như "my password" nếu tôi loại bỏ mật khẩu này tất cả mọi thứ đang làm việc tốt nhưng khi tôi sử dụng khoản mật khẩu, nó mang lại cho tôi lỗi trong connection.open() cú pháp mà

File opened that is not a database file 
file is encrypted or is not a database 

tôi tìm kiếm trên mạng và tìm thấy một số vấn đề phiên bản nhưng tôi đang sử dụng phiên bản 3 chỉ như tôi đã nói trong mối liên hệ chuỗi i cũng đã cố gắng loại bỏ "phiên bản = 3" nhưng vấn đề vẫn giữ nguyên.

Tôi đang thực hiện lần đầu tiên này, giải pháp của nó là gì?

Trả lời

7

Khi bạn chỉ định mật khẩu trong chuỗi kết nối và cơ sở dữ liệu đã tồn tại, SQLite giả định cơ sở dữ liệu được mã hóa và sẽ cố gắng giải mã bằng mật khẩu đã nói. Nếu bạn chưa đặt mật khẩu trên cơ sở dữ liệu, điều này sẽ dẫn đến lỗi "tệp được mã hóa", vì mật khẩu được cung cấp không thể được sử dụng để giải mã cơ sở dữ liệu không được mã hóa.

Bạn có thể xóa cơ sở dữ liệu và SQLite sẽ tạo cơ sở dữ liệu được mã hóa mới bằng mật khẩu trong chuỗi kết nối. Hoặc, bạn có thể mã hóa cơ sở dữ liệu hiện tại của bạn bằng cách sử dụng phương pháp 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"); 

tham khảo: Encrypting, decrypting and attaching to encrypted databases

+0

+1, cảm ơn rất nhiều, nhưng lần đầu tiên nó hoạt động hoàn hảo nhưng khi tôi chạy ứng dụng lần thứ hai nó lại hiển thị cùng ngoại lệ trên con.open rằng "Tệp đã mở không phải là tệp cơ sở dữ liệu được mã hóa hoặc không phải là cơ sở dữ liệu " – Mogli

+1

@harhar, vui lòng phác thảo các bước bạn đã thực hiện để mã hóa cơ sở dữ liệu của mình. Nếu bạn đã sử dụng phương thức 'ChangePassword()', bạn sẽ muốn loại bỏ nó khỏi các cuộc gọi tiếp theo. – 2Toad

+0

sau con.Open(); tôi viết con.ChangePassword ("mật khẩu"); và sau khi làm việc với nó, tôi làm con.ChangePassword (""); và cuối cùng là con.Close(); cái này sai rồi hả ? – Mogli

2

câu trả lời 2Toad là chủ yếu là chính xác, nhưng tôi muốn thêm của riêng tôi vì có một số giải thích được thực hiện. Như 2Toad cho biết, điều này là chính xác:

Khi bạn chỉ định mật khẩu trong chuỗi kết nối và cơ sở dữ liệu đã tồn tại, SQLite giả định cơ sở dữ liệu được mã hóa và sẽ cố gắng giải mã bằng mật khẩu đã nói. Nếu bạn chưa đặt mật khẩu trên cơ sở dữ liệu, điều này sẽ dẫn đến lỗi "tệp được mã hóa", vì mật khẩu được cung cấp không thể được sử dụng để giải mã cơ sở dữ liệu không được mã hóa.

Nhưng lỗi này cũng có thể xảy ra nếu bạn cố gắng sử dụng conn.SetPassword("something") sau khi bạn đã có một số khác trong chuỗi kết nối. Hoặc nếu bạn làm conn.ChangePassword("somethingelse"), nhưng vẫn có Password=something trong chuỗi kết nối.

Có một số kịch bản để xem xét:

  1. Cơ sở dữ liệu đã được áp dụng một mật khẩu, và nó là trong chuỗi kết nối.
  2. Bạn có mật khẩu trong chuỗi kết nối, nhưng cơ sở dữ liệu không được áp dụng, hoặc mật khẩu trong chuỗi không khớp với DB.
  3. Cơ sở dữ liệu chưa bao giờ có mật khẩu và bạn muốn thay đổi nó.
  4. Cơ sở dữ liệu đã có mật khẩu và bạn muốn thay đổi nó.

Nghị quyết:

  1. Vì vậy, mã 2Toad cung cấp để thực hiện conn.ChangePassword("somethingelse") chỉ là một nửa-chính xác và không đưa vào tài khoản bạn đang ở đâu, những gì khác mà bạn đã thực hiện, và những gì bạn muốn làm trong tương lai. Nếu bạn có một mật khẩu hiện tại và bạn muốn thay đổi nó, điều này là chính xác, nhưng bạn cũng phải chắc chắn chuỗi kết nối được cập nhật sau đó, hoặc các kết nối tiếp theo sẽ thất bại với lỗi file is encrypted.

  2. Kịch bản này xảy ra nếu bạn để trống mật khẩu bằng cách sử dụng conn.SetPassword("") và sau đó thử conn.ChangePassword("somethingelse") mà không cần kết nối với cơ sở dữ liệu mà không có Password=something trong chuỗi kết nối. Điều đó Password=something sẽ phải được loại bỏ khỏi chuỗi kết nối, bởi vì mật khẩu đã được gỡ bỏ lập trình từ DB và DB sẽ cố gắng kết nối với điều đó. Nếu nó không bị xóa khỏi chuỗi kết nối cùng một lúc vì nó bị xóa khỏi DB theo lập trình, bạn sẽ nhận được cùng một lỗi file is encrypted.

  3. Vì tôi bắt đầu bằng cách thực hiện conn.SetPassword("something") ngay từ đầu khi không có mật khẩu (và tôi tin đây là cách để làm điều đó), tôi không thể xác minh điều sau mà không tạo một DB SQLite khác, nhưng tôi không tin bạn có thể gọi số conn.ChangePassword("something") nếu bạn chưa bao giờ có mật khẩu ngay từ đầu. Bạn nên làm conn.SetPassword("something") cho tập hợp ban đầu, và sau đó đặt Password=something trong chuỗi kết nối của bạn.

  4. Con đường tôi đã làm một sự thay đổi của một mật khẩu là nơi tôi đã làm conn.ChangePassword("somethingelse") chỉ sau khi làm conn.SetPassword("") và thanh toán bù trừ các Password=something từ chuỗi kết nối:

    // 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 
    

này làm việc ra tốt đẹp. Tôi cho rằng bạn cũng có thể không rõ ràng nó từ chuỗi kết nối và chỉ cần làm conn.ChangePassword("somethingelse"), và sau đó thêm Password=somethingelse chuỗi của bạn, sau đó:

// 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 

Cá nhân, tôi lưu trữ các mật khẩu được mã hóa như trong một ứng dụng (web) .config và gọi nó thành một biến trong tải ứng dụng của tôi và tự động tạo chuỗi kết nối của tôi từ nó. Điều đó tôi biết, nếu bạn xóa một SQLite DB và cố gắng gọi nó, bạn sẽ chỉ nhận được một lỗi - không phải là một tái tạo SQLite DB với một mật khẩu mới từ chuỗi kết nối của bạn - ít nhất là khi sử dụng và gọi điện thoại nó từ một ứng dụng C# .NET.

CẬP NHẬT Nếu bạn cần một chức năng sẽ được sử dụng để cập nhật mật khẩu sau khi bạn đã có một, bạn không muốn có .SetPassword(), nhưng .ChangePassword(). Tôi tìm thấy nó cũng tốt hơn để luôn luôn trống nó ra, sau đó thay đổi nó, như trong ví dụ đầu tiên của tôi trong # 4.

+0

Tất cả bốn kịch bản mà bạn đã đề cập ở trên đều rất tự giải thích ... còn nguyên vẹn tôi cần .... Đó là một giải thích tuyệt vời. Cảm ơn UpVoted :) – Mogli

+0

@Mogli, cảm ơn. Tôi tìm thấy trong cái nóng của "chỉ cần cố gắng để có được-the-damn-điều-to-work", tôi nghĩ một danh sách kiểm tra toàn diện là tốt hơn với các kịch bản nhất định hơn để nói để chỉ cần làm "x", như chỉ cần làm "x" có thể khiến bạn gặp rắc rối nếu bạn không chú ý đến những gì bạn đang thực sự cố gắng làm, với hoàn cảnh thực tế của bạn. :) – vapcguy

Các vấn đề liên quan