2013-04-16 15 views
11

Pracuję w .net aplikacji Windows 2.0 z SQLite bazy danych, mój ciąg połączenia pozostaje w app.config jaksqlite nie można otworzyć pliku bazy danych jest zaszyfrowany lub nie jest bazą danych?

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

w ciągu połączenia i hasła zdefiniowanego jako „moje_hasło” Jeśli usunąć hasło to wszystko działa dobrze, ale kiedy użyć klauzuli hasła, to daje mi błąd w Connection.Open składnia(), która

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

Szukałem na sieci i znalazłem kilka wersji problem, ale używam tylko w wersji 3, jak stwierdziłem w związku ciąg próbowałem również usunięcie "version = 3", ale problem pozostaje ten sam.

Robię to po raz pierwszy, jakie jest rozwiązanie tego?

Odpowiedz

7

Po określeniu hasła w łańcuchu połączenia, a baza danych już istnieje, SQLite zakłada, że ​​baza danych jest zaszyfrowana i spróbuje ją odszyfrować za pomocą wspomnianego hasła. Jeśli jeszcze nie ustawiłeś hasła w bazie danych, spowoduje to błąd "plik jest zaszyfrowany", ponieważ podane hasło nie może zostać użyte do odszyfrowania niezaszyfrowanej bazy danych.

Możesz usunąć bazę danych, a SQLite utworzy nową zaszyfrowaną bazę danych, używając hasła w ciągu połączenia. Albo można szyfrować swoją istniejącą bazę danych przy użyciu metody 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"); 

referencyjny: Encrypting, decrypting and attaching to encrypted databases

+0

+1, dziękuję, że działa, ale tylko za pierwszym razem działało bezbłędnie, ale kiedy uruchomię aplikację po raz drugi, to ponownie pokazuje ten sam wyjątek na con.open, że "Plik otwarty, który nie jest plikiem bazy danych plik jest zaszyfrowane lub nie jest bazą danych " – Mogli

+1

@harhar proszę opisać kroki podjęte w celu zaszyfrowania bazy danych. Jeśli użyłeś metody 'ChangePassword()', będziesz chciał usunąć ją z kolejnych połączeń. – 2Toad

+0

after con.Open(); piszę con.ChangePassword ("hasło"); i po pracy z nim robię con.ChangePassword (""); i wreszcie con.Close(); czy to źle ? – Mogli

2

odpowiedź 2Toad jest w większości poprawne, ale chciałem dodać własną rękę, ponieważ istnieją pewne wyjaśnienia mają być wykonane. Jak powiedział 2Toad, jest to poprawne:

Po określeniu hasła w łańcuchu połączenia, a baza danych już istnieje, SQLite zakłada, że ​​baza danych jest zaszyfrowana i spróbuje ją odszyfrować za pomocą wspomnianego hasła. Jeśli jeszcze nie ustawiłeś hasła w bazie danych, spowoduje to błąd "plik jest zaszyfrowany", ponieważ podane hasło nie może zostać użyte do odszyfrowania niezaszyfrowanej bazy danych.

Ale ten błąd może się również zdarzyć, jeśli spróbujesz użyć conn.SetPassword("something") po tym, jak już masz inny w ciągu połączenia. Lub jeśli robisz conn.ChangePassword("somethingelse"), ale wciąż masz Password=something w ciągu połączenia.

Istnieje kilka scenariuszy do rozważenia:

  1. Baza była stosowana hasło, i to w ciągu połączenia.
  2. Masz hasło w ciągu połączenia, ale baza danych nie ma zastosowanej lub hasło w ciągu nie pasuje do DB.
  3. Baza danych nigdy nie miała hasła i chcesz to zmienić.
  4. Baza danych ma hasło i chcesz je zmienić.

rozdzielczościach:

  1. Więc kod 2Toad przewidziane do wykonywania conn.ChangePassword("somethingelse") jest tylko pół-poprawny i nie bierze pod uwagę, gdzie jesteś, co jeszcze zrobiłeś, i co chcesz robić w przyszłości. Jeśli masz już istniejące hasło i chcesz je zmienić, jest to poprawne, ale musisz również upewnić się, że ciąg połączenia zostanie zaktualizowany później, lub kolejne połączenia zakończą się niepowodzeniem z błędem file is encrypted.

  2. Ten scenariusz się dzieje, jeśli puste hasło używając conn.SetPassword("") a następnie spróbuj conn.ChangePassword("somethingelse") bez wcześniejszego podłączenia do bazy danych bez Password=something w ciągu połączenia. Ten Password=something musiałby zostać usunięty z ciągu połączenia, ponieważ hasło zostało usunięte programowo z DB, a DB spróbuje połączyć się z tym. Jeśli nie zostanie usunięty z ciągu połączenia w tym samym czasie, co programowo usunięty z bazy danych, otrzymasz ten sam błąd file is encrypted.

  3. Ponieważ zacząłem od zrobienia conn.SetPassword("something") na samym początku, gdy nie miałem hasła (i uważam, że jest to sposób na zrobienie tego), nie mogę zweryfikować poniższych bez tworzenia kolejnej bazy danych SQLite, ale nie wierzę, że możesz zadzwonić pod numer conn.ChangePassword("something"), jeśli nigdy nie masz hasła. Powinieneś wykonać conn.SetPassword("something") dla zestawu początkowego, a następnie umieścić Password=something w ciągu połączenia.

  4. Sposób zrobiłem zmianę hasła było gdzie zrobiłem conn.ChangePassword("somethingelse") dopiero po wykonaniu conn.SetPassword("") i wyczyszczenie Password=something z ciągu połączenia:

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

To działało w porządku. Przypuszczam, że również nie można usunąć go z ciągu połączenia i po prostu zrobić conn.ChangePassword("somethingelse"), a następnie dodać Password=somethingelse do napisu, potem:

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

Osobiście zapisać jako zaszyfrowane hasło w aplikacji (WEB) .config plik i wywołaj go do zmiennej w moim aplikacji onload i dynamicznie buduj z niej swój ciąg połączenia.

Którą znam, jeśli usuniesz bazę danych SQLite i spróbujesz ją wywołać, po prostu otrzymasz błąd - nie ponownie utworzoną bazę danych SQLite z nowym hasłem z ciągu połączenia - przynajmniej podczas używania i wywoływania to z aplikacji C# .NET.

UPDATE Jeśli potrzebujesz funkcję, która będzie używana do aktualizacji hasła po masz już jeden, że nie chcesz mieć .SetPassword(), ale .ChangePassword(). Zauważyłem, że lepiej jest zawsze go wyłuskać, a potem zmienić, jak w moim pierwszym przykładzie w punkcie 4.

+0

Wszystkie cztery scenariusze, o których wspomniałeś powyżej, są bardzo zrozumiałe ... tak naprawdę to potrzebowałem .... To było świetne wytłumaczenie. Dzięki UpVoted :) – Mogli

+0

@Mogli, dzięki. Pomyślałem, że w upale "po prostu próbując zdobyć-to-cholera-coś-do-pracy", myślałem, że kompleksowa lista kontrolna była lepsza z podanymi scenariuszami, niż po prostu powiedzieć "x", jak po prostu robi "x" może wpędzić cię w kłopoty, jeśli nie zwracasz uwagi na to, co faktycznie próbujesz zrobić, biorąc pod uwagę faktyczną okoliczność. :) – vapcguy

Powiązane problemy