2013-05-14 12 views
6

Używam SQLCipher for Android i próbuję ustalić prawidłowy sposób sprawdzenia, czy podane przez użytkownika hasło jest prawidłowe.Czy istnieje poprawny sposób sprawdzenia, czy podane przez użytkownika hasło SQLCipher jest poprawne w systemie Android?

Moja pierwsza skłonność polegała na próbie otwarcia bazy danych z podanym hasłem, za pomocą implementacji SQLCipher z SQLiteOpenHelper.getReadableDatabase(password), a następnie wyświetleniu SQLiteException, która wyskakuje.

To działa, ale problem polega na tym, że interfejs API systemu Android faktycznie owija podstawowe wywołania C, robi to za Ciebie - szczególnie, gdy otwierasz bazę danych przy użyciu interfejsu API systemu Android, otwiera się baza danych , uruchamia natywną metodę C-level sqlite3_key (z podanym hasłem), a następnie próbuje ustawić ustawienia regionalne w bazie danych, niezależnie od tego, czy podane hasło było poprawne.

W tym momencie biblioteka Android próbuje ustawić ustawienia narodowe, a bazowa baza danych wyrzuca "zaszyfrowaną lub nie bazę danych" SQLiteException, która jest przechwytywana i ponownie zgłaszana; ale zanim to nastąpi, niepowiązany błąd jest zapisywany w dziennikach, zasadniczo mówiąc, że ustawienia regionalne nie mogą zostać ustawione, a baza danych jest zamykana (z dołączonym śladem stosu). Ponieważ jest to napisane specjalnie przez bibliotekę Androida, nie mogę tego ukryć, pozostawiając brzydki błąd w dziennikach, który nie jest związany z moim pierwotnym problemem, który po prostu przekazałem błędnie.

Ponieważ biblioteka Android nie ujawnia wywołań poziomu C, nie mogę po prostu użyć metody opisanej w dokumentacji interfejsu API SQLCipher dotyczącej Testing the Key, ponieważ nie mam dostępu do bezpośredniego otwierania bazy danych.

Pochylam się do korzystania z SQLiteDatabaseHook, ale jak najlepiej mogę powiedzieć, to wyklucza moje użycie SQLiteOpenHelper, co nie wydaje się stanowić sposób na ustawienie haka.

Czy ktoś jeszcze zna lepszy sposób sprawdzenia, czy wejściowe hasło prawidłowo odszyfrowuje bazę danych SQLCipher za pośrednictwem interfejsu API SQLCipher Android? Całkowicie oczekiwałbym wywołania metody i sprawdzenia, czy wyjątek jest zgłaszany - nie chcę, aby operacja próbowała wykonywać przetwarzanie obce (jak ustawienia regionalne) w bazie danych i zapisywać całkowicie niewysłowiony błąd w moich dziennikach.

+0

”...to jest faktycznie niezwiązane z moim pierwotnym problemem, który był po prostu tym, że przekazałem błędne hasło "- nie, to jest oryginalny problem: przekazałeś złe hasło, dlatego operacja set-locale nie powiodła się." Mogę po prostu użyj metody opisanej w dokumentacji interfejsu API SQLCipher dotyczącej testowania klucza ... "- twoje wyniki będą identyczne z tymi, które obecnie uzyskujesz, chyba że bez żadnych zewnętrznych śladów w LogCat. Co więcej, jakie są twoje kryteria dla "lepszego sposobu"? – CommonsWare

+0

Przepraszam, najwyraźniej nie wyjaśniłem się, jedyne, co chcę zrobić, to sprawdzić, czy przekazałem błędne hasło. Całkowicie zgadzam się, że moje wyniki byłyby takie same (wywołanie, sprawdź błąd). Moje kryteria "lepszego sposobu" to BEZ niepotrzebnego przetwarzania setLocale i błędu – mWillis

+0

Po prostu zgłoś problem, aby nie rejestrować błędu i nie martwić się o niego. , Polecam sqlcipher Google Group dla m ore pomocy. – CommonsWare

Odpowiedz

0

SQLCipher dla Androida nie wie, że hasło podałeś jest nieprawidłowy po sqlite3_key rozmowy, jako klucz bazy danych nie jest stosowany, dopóki polecenie SQL jest wydawane na bazie po sqlite3_key, takich jak metoda setLocale(...) ty odniesienie powyżej. Problem polega na tym, że podanie nieprawidłowego klucza może być tylko jednym z możliwych innych scenariuszy, które mogą stanowić problem w momencie, gdy wykonywana jest pierwsza instrukcja SQL. Uszkodzony plik danych, nieudane sprawdzanie HMAC lub otwarcie pliku bez bazy danych może spowodować pojawienie się tego samego komunikatu o błędzie. Aby uzyskać szczegółowy opis tego, przeczytaj ten thread. Najlepiej wychwycić wyjątek podczas próby otwarcia bazy danych i obsługiwać ją w aplikacji klienckiej.

+0

Zdecydowanie dostaję to wszystko. Problem w tym, że nie mam możliwości powtórzenia "Testowania klucza", jak w moim pytaniu. Dzięki interfejsowi API iOS mam dostęp do API C, więc mogę otworzyć bazę danych, 'pragma key', a następnie spróbować odczytać z' sqlite_master'. Jeśli to spowoduje błąd, mogę go złapać i nazwać to dniem. Jednak dzięki Androidowi API nie mogę tego zrobić tak prosto, ponieważ muszę wywołać 'openOrCreateDatabase', która otwiera plik db, wpisuje go, a następnie próbuje ustawić ustawienia narodowe, w którym występuje błąd. To nie jest takie złe, ale nieprzekraczalny wynik w dzienniku jest frustrujący. – mWillis

0

Nie mam lepszego sposobu na przetestowanie tego. Po prostu chcę podać trochę kodu, więc gdy inni ludzie to sprawdzą, mogą znaleźć przydatne fragmenty kodu. Przynajmniej kiedy znalazłem to pytanie, bym kochał, aby zobaczyć, jak zrobić trochę kodu do check-up :)

The Way I zrobić to w android jest taka:

// Simply get an instance of SQLiteOpenHelper. 
    dbHelperObj = myDatabase.getInstance(this, str_username, version); 

    // Now we try to open the database with the password from the user. 
    try { 
     dbObj = dbHelperObj.getReadableDatabase(str_password); 

    // The only possible error now must be a wrong password. 
    } catch (Exception e) { 
     dbHelperObj.close(); 

     // Do stuff to tell the user he provided a wrong password. 
    } 
Powiązane problemy