{"action":"created","issue":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1233","repository_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios","labels_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1233/labels{/name}","comments_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1233/comments","events_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1233/events","html_url":"https://github.com/couchbase/couchbase-lite-ios/issues/1233","id":151992552,"number":1233,"title":"Failure to encrypt SQLite database when using WAL journaling","user":{"login":"brendand","id":586075,"avatar_url":"https://avatars.githubusercontent.com/u/586075?v=3","gravatar_id":"","url":"https://api.github.com/users/brendand","html_url":"https://github.com/brendand","followers_url":"https://api.github.com/users/brendand/followers","following_url":"https://api.github.com/users/brendand/following{/other_user}","gists_url":"https://api.github.com/users/brendand/gists{/gist_id}","starred_url":"https://api.github.com/users/brendand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brendand/subscriptions","organizations_url":"https://api.github.com/users/brendand/orgs","repos_url":"https://api.github.com/users/brendand/repos","events_url":"https://api.github.com/users/brendand/events{/privacy}","received_events_url":"https://api.github.com/users/brendand/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-04-30T00:21:01Z","updated_at":"2016-04-30T00:37:41Z","closed_at":null,"body":"I am having troubles encrypting a database where the journal mode of the db.sqlite file is in WAL mode. I get the error message right after encrypting it. And then when I open up the database file after I restart my app, I get a 'database disk image malformed' error.\r\n\r\n```\r\nDB Error: 26 \"file is encrypted or is not a database\"\r\n2016-04-29 17:59:59.453 Tap Forms[83056:10745308] DB Query: SELECT count(*) FROM sqlite_master\r\n2016-04-29 17:59:59.453 Tap Forms[83056:10745308] *** Assertion failure in -[CBL_FMDatabase executeQuery:withArgumentsInArray:orVAList:], /Users/brendan/Projects/iPhone/couchbase-lite-ios/vendor/fmdb/src/FMDatabase.m:635\r\nDB Error: 26 \"file is encrypted or is not a database\"\r\n```\r\n\r\nHere's the relevant parts of a back-trace of when the error occurs:\r\n\r\n```\r\n(lldb) bt\r\n* thread #1: tid = 0xa3f5dc, 0x00007fff89f9bf4e libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 5.1\r\n    frame #0: 0x00007fff89f9bf4e libobjc.A.dylib`objc_exception_throw\r\n    frame #1: 0x00007fff8eea11ca CoreFoundation`+[NSException raise:format:arguments:] + 106\r\n    frame #2: 0x00007fff91c527d6 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198\r\n    frame #3: 0x0000000100df3acc CouchbaseLite`-[CBL_FMDatabase executeQuery:withArgumentsInArray:orVAList:](self=0x00006180000b5780, _cmd=\"executeQuery:withArgumentsInArray:orVAList:\", sql=@\"SELECT count(*) FROM sqlite_master\", arrayArgs=0x0000000000000000, args=0x00007fff5fbfbbb0) + 1132 at FMDatabase.m:635\r\n    frame #4: 0x0000000100df5b2a CouchbaseLite`-[CBL_FMDatabase(self=0x00006180000b5780, _cmd=\"intForQuery:\", query=@\"SELECT count(*) FROM sqlite_master\") intForQuery:] + 394 at FMDatabaseAdditions.m:33\r\n    frame #5: 0x0000000100d6eec8 CouchbaseLite`-[CBL_SQLiteStorage decryptWithKey:error:](self=0x0000618000660c00, _cmd=\"decryptWithKey:error:\", encryptionKey=0x00006180000032b0, outError=domain: nil - code: 0) + 584 at CBL_SQLiteStorage.m:259\r\n    frame #6: 0x0000000100d6ea07 CouchbaseLite`-[CBL_SQLiteStorage openFMDB:](self=0x0000618000660c00, _cmd=\"openFMDB:\", outError=domain: nil - code: 0) + 487 at CBL_SQLiteStorage.m:211\r\n    frame #7: 0x0000000100d706b0 CouchbaseLite`-[CBL_SQLiteStorage open:](self=0x0000618000660c00, _cmd=\"open:\", outError=domain: nil - code: 0) + 112 at CBL_SQLiteStorage.m:378\r\n    frame #8: 0x0000000100d70560 CouchbaseLite`__49-[CBL_SQLiteStorage actionToChangeEncryptionKey:]_block_invoke.202(.block_descriptor=0x0000618000453230, outError=domain: nil - code: 0) + 96 at CBL_SQLiteStorage.m:364\r\n    frame #9: 0x0000000100dd3b4e CouchbaseLite`-[MYAction doActionFromArray:](self=0x0000618000669600, _cmd=\"doActionFromArray:\", actionArray=@\"13 elements\") + 142 at MYAction.m:155\r\n    frame #10: 0x0000000100dd38f0 CouchbaseLite`-[MYAction cleanUp:](self=0x0000618000669600, _cmd=\"cleanUp:\", outError=0x0000000000000000) + 240 at MYAction.m:125\r\n    frame #11: 0x0000000100dd3a23 CouchbaseLite`-[MYAction run:](self=0x0000618000669600, _cmd=\"run:\", outError=domain: nil - code: 0) + 115 at MYAction.m:139\r\n    frame #12: 0x0000000100d55dc5 CouchbaseLite`-[CBLDatabase changeEncryptionKey:error:](self=0x0000618000127440, _cmd=\"changeEncryptionKey:error:\", newKeyOrPassword=0x0000007473657445, outError=domain: nil - code: 0) + 661 at CBLDatabase.m:285\r\n  * frame #13: 0x00000001002353df Tap Forms`-[PreferencesWindowController unlockAction:](self=0x0000000107403140, _cmd=\"unlockAction:\", sender=0x0000618000148560) + 2079 at PreferencesWindowController.m:538\r\n```\r\n\r\nI normally do the encryption in an asynchronous block using `CBLManager's doAsync`, and I thought maybe that was what causes the problem. I also tried `tellBackgroundDatabaseNamed` and also just calling `changeEncryptionKey:` from the main thread, but all lead to a corrupted database file that could not even be opened afterwards.\r\n\r\nI've just discovered that when this failure occurs, the .wal file happens to not be encrypted, but the .shm and .sqlite files are encrypted. If I delete the .wal and .shm files and open the database, I'm correctly asked for the encryption key and when I enter it, I'm able to open the database file just fine.\r\n\r\nSo there's something weird going on where the .wal file isn't being encrypted along with the .shm and .sqlite files. I'm using the latest 3.4.0 version of SQLCipher.\r\n\r\n--------\r\n* SQLCipher version: 3.4.0\r\n* Version:   1.3 beta dev branch commit 51b723efd3c2cd966006762e46dac2d90652e6ec\r\n* Client OS: OS X 10.11.4\r\n* Server:    n/a\r\n"},"comment":{"url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/comments/215915594","html_url":"https://github.com/couchbase/couchbase-lite-ios/issues/1233#issuecomment-215915594","issue_url":"https://api.github.com/repos/couchbase/couchbase-lite-ios/issues/1233","id":215915594,"user":{"login":"brendand","id":586075,"avatar_url":"https://avatars.githubusercontent.com/u/586075?v=3","gravatar_id":"","url":"https://api.github.com/users/brendand","html_url":"https://github.com/brendand","followers_url":"https://api.github.com/users/brendand/followers","following_url":"https://api.github.com/users/brendand/following{/other_user}","gists_url":"https://api.github.com/users/brendand/gists{/gist_id}","starred_url":"https://api.github.com/users/brendand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brendand/subscriptions","organizations_url":"https://api.github.com/users/brendand/orgs","repos_url":"https://api.github.com/users/brendand/repos","events_url":"https://api.github.com/users/brendand/events{/privacy}","received_events_url":"https://api.github.com/users/brendand/received_events","type":"User","site_admin":false},"created_at":"2016-04-30T00:37:41Z","updated_at":"2016-04-30T00:37:41Z","body":"I actually think the .shm file is not also encrypted now. It just mostly had upside down question marks in it, so I thought it was encrypted, but I don't think it is. So the .sqlite file is encrypted, but not the ancillary files and that's what causes the malformed disk image error.\r\n\r\nI notice that new CBL database files have the journal_mode set to WAL. I'm going to try changing that code in `CBL_SQLiteStorage.m` to DELETE and then try again to see what happens.\r\n\r\n```\r\n    if (isNew && ![self initialize: @\"PRAGMA journal_mode=DELETE; BEGIN TRANSACTION\" error: outError])\r\n```\r\n\r\ninstead of:\r\n\r\n```\r\n    if (isNew && ![self initialize: @\"PRAGMA journal_mode=WAL; BEGIN TRANSACTION\" error: outError])\r\n```\r\n\r\nHowever, I would prefer to have WAL mode for the performance benefits."}}