Hello,
Today I started a new swift project, and installed SQLCipher via cocoapods (4.0 it appears). After getting it up and running I imported an existing encrypted database from an objective C project, but I cannot open it. I just receive the error file is not a database (I am using sample code from the SQLCipher tutorial for test projects)
Accessing the same database in another test project, using the equivalent objective C code works fine. The objective c project was set up with manual installation, and it is at least a year older - not sure of exact version.
As a test I created and encrypted a new database using the objective c sample code in the old project and then tried to open it with same swift equivalent code using new 4.0 and no dice. same error. My guess is 4.0 isn’t compatible with databases created using the older version? Please advise.
Objective C code - older SQLCipher version
NSString *databasePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent: @"test.db"];
sqlite3 *db;
sqlite3_stmt *stmt;
bool sqlcipher_valid = NO;
if (sqlite3_open([databasePath UTF8String], &db) == SQLITE_OK) {
const char* key = [@"helloWorld" UTF8String];
sqlite3_key(db, key, strlen(key));
if (sqlite3_exec(db, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
if(sqlite3_prepare_v2(db, "PRAGMA cipher_version;", -1, &stmt, NULL) == SQLITE_OK) {
if(sqlite3_step(stmt)== SQLITE_ROW) {
const unsigned char *ver = sqlite3_column_text(stmt, 0);
if(ver != NULL) {
sqlcipher_valid = YES;
NSString *create = @"CREATE TABLE Test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT)";
if(sqlite3_exec(db, [create UTF8String], NULL, NULL, NULL)==SQLITE_OK)
{
NSLog(@".. TABLE Added ..");
}
// password is correct (or database initialize), and verified to be using sqlcipher
}
}
sqlite3_finalize(stmt);
}
}
sqlite3_close(db);
}
New swift code - SQLCipher 4.0 (this fails to validate key on same database created with previous code)
let path = NSSearchPathForDirectoriesInDomains(
.documentDirectory, .userDomainMask, true
).first!
var rc: Int32
var db: OpaquePointer? = nil
var stmt: OpaquePointer? = nil
let password: String = "helloWorld"
NSLog("\(SQLITE_OK)")
rc = sqlite3_open("\(path)/test.db", &db)
if (rc != SQLITE_OK) {
let errmsg = String(cString: sqlite3_errmsg(db))
NSLog("Error opening database: \(errmsg)")
return
}
rc = sqlite3_key(db, password, Int32(password.utf8CString.count))
if (rc != SQLITE_OK) {
let errmsg = String(cString: sqlite3_errmsg(db))
NSLog("Error setting key: \(errmsg)")
}
rc = sqlite3_prepare(db, "PRAGMA cipher_version;", -1, &stmt, nil)
if (rc != SQLITE_OK) {
let errmsg = String(cString: sqlite3_errmsg(db))
NSLog("Error preparing SQL: \(errmsg)")
}
rc = sqlite3_step(stmt)
if (rc == SQLITE_ROW) {
NSLog("cipher_version: %s", sqlite3_column_text(stmt, 0))
} else {
let errmsg = String(cString: sqlite3_errmsg(db))
NSLog("Error retrieiving cipher_version: \(errmsg)")
}
let create = "CREATE TABLE Test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT)";
if sqlite3_exec(db, create, nil, nil, nil) == SQLITE_OK {
print(".. TABLE Added ..");
} else {
let errmsg = String(cString: sqlite3_errmsg(db))
print("\(errmsg)")
}
sqlite3_finalize(stmt)
sqlite3_close(db)
Thanks!