2013-05-14 27 views
6

我正在使用SQLCipher for Android,並試圖確定測試用戶提供的密碼是否有效的正確方法。是否有正確的方法來測試用戶提供的SQLCipher密碼在Android上是否有效?

我的第一個想法是嘗試使用給定密碼打開數據庫,使用SQLCipher實現SQLiteOpenHelper.getReadableDatabase(password),然後捕獲彈出的SQLiteException

這是行得通的,但問題在於,由於Android API實際上包裝了底層的C調用,它爲您做了很多工作 - 具體來說,當您使用Android API打開數據庫時,它會打開數據庫,運行本地C級sqlite3_key方法(使用提供的密碼),然後嘗試設置數據庫的區域設置,無論提供的密碼是否正確。

此時,Android庫會嘗試設置區域設置,並且底層數據庫會拋出「已加密或未加密的數據庫」SQLiteException,這會被捕獲並重新生成;但在此之前,將一個無關的錯誤寫入日誌,基本上說,不能設置區域設置並關閉數據庫(使用包含的堆棧跟蹤)。因爲這是由Android庫專門編寫的,所以我無法抑制它,在日誌中留下一個與我的原始問題無關的醜陋錯誤,這只是我傳遞了錯誤的密碼。

由於Android庫不公開C級調用,因此我不能僅使用SQLCipher API文檔中描述的有關Testing the Key的方法,因爲我無權直接打開數據庫。

我傾向於使用SQLiteDatabaseHook,但盡我所知,這排除了我使用SQLiteOpenHelper,它似乎沒有提供設置掛鉤的方法。

是否有其他人知道任何更好的方法來測試輸入密碼短語是否通過SQLCipher Android API正確解密SQLCipher數據庫?我完全希望調用一個方法並檢查拋出的異常 - 我不想要的操作是嘗試對數據庫執行無關處理(如set locale),併爲我的日誌寫入完全不可克服的錯誤。

+0

」 ...這實際上與我原來的問題無關,只是我傳遞了錯誤的密碼「 - 不,這是原始問題:你傳遞了錯誤的密碼,這就是set-locale操作失敗的原因。」我可以使用SQLCipher API文檔中描述的有關測試密鑰的方法...「 - 除了可能沒有LogCat中的任何無關痕跡之外,您的結果將與您目前獲得的結果相同。除此之外,您的標準是什麼對於「任何更好的方式」? – CommonsWare

+0

我很抱歉,我顯然沒有讓自己清楚,我想要做的是檢查我是否通過了錯誤的密碼,我完全同意我的結果是一樣的調用,檢查錯誤)我的「任何更好的方法」的標準是沒有額外的setLocale處理和錯誤 – mWillis

+0

我只是提出一個問題,讓他們不記錄錯誤,不用擔心它。 ,我建議sqlcipher Google Group for m礦石援助。 – CommonsWare

回答

0

SQLCipher爲Android不知道你提供的密碼是無效繼sqlite3_key呼叫,作爲數據庫密鑰沒有使用,直到一個SQL命令是繼sqlite3_key針對數據庫發出的,如setLocale(...)方法你以上參考。問題是,提供無效密鑰可能只是可能的其他情況之一,可能是第一個SQL語句執行時的問題。一個損壞的數據文件,一個失敗的HMAC檢查或打開一個非數據庫文件可能會導致相同的錯誤信息。有關這方面的詳細說明,請查閱此thread。嘗試打開數據庫並在客戶端應用程序中相應處理時最好捕獲異常。

+0

我絕對明白這一切。我遇到的問題是,我無法像在我的問題中那樣複製「測試密鑰」。通過iOS API,我可以訪問C API,所以我可以打開數據庫'pragma key',然後嘗試從'sqlite_master'讀取數據。如果這引發了一個錯誤,我可以捕捉到並稱之爲一天。然而,通過Android API,我不能這麼做,因爲我必須調用'openOrCreateDatabase'來打開數據庫,然後鍵入數據,然後嘗試設置語言環境,這是發生錯誤的地方。這並不壞,但不可克服的日誌輸出令人沮喪。 – mWillis

0

我沒有更好的測試方法。我只想提供一些代碼,所以當其他人查看這些代碼時,他們可能會發現一些有用的代碼片段。 至少當我發現這個問題,我會喜歡看到一些代碼是如何做的體檢:)

我這樣做是在android系統的方式是這樣的:

// 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. 
    } 
相關問題