Unable to decrypt encrypted database in swift 3


#1

Hi, my encryption code works very well, but i cannot decrypt it .please help me.

my encryption code is below
var db: OpaquePointer? = nil

    let databasePath = Util.getPath("demo.sqlite")


    if (sqlite3_open(databasePath, &db) == SQLITE_OK) {

        let aStr = String(format: "%@/Documents/encrypted1.sqlite",NSHomeDirectory())
        print("Database Path: ", aStr)
        
        
        let newQuery = "ATTACH DATABASE '\(aStr)' AS encrypted KEY 'ganesh';"
        print("NewQuery: ", newQuery)
        
       
        if sqlite3_exec(db, newQuery, nil, nil, nil) == SQLITE_OK {
            
            if sqlite3_exec(db, "SELECT sqlcipher_export('encrypted');", nil, nil, nil) == SQLITE_OK{
                
              
                if sqlite3_exec(db, "DETACH DATABASE encrypted;", nil, nil, nil) == SQLITE_OK{
                    
                  
                    print("Encryption succesful")

                    
                }else{
                
                    
                    let errmsg = String(cString: sqlite3_errmsg(db))
                    NSLog("DETACH DATABASE encrypted: \(errmsg)")
                }
                
            
            }else{
                let errmsg = String(cString: sqlite3_errmsg(db))
                NSLog("Error sqlcipher_export: \(errmsg)")
            }
           
        }else{
        
            let errmsg = String(cString: sqlite3_errmsg(db))
            NSLog("Error opening database: \(errmsg)")
            
        }
        
        
   
        sqlite3_close(db);
        
        
    
    }else{
    
        sqlite3_close(db);
        sqlite3_errmsg(db);
        
    }

/////// here is my decryption code

var db: OpaquePointer? = nil
var stmt: OpaquePointer? = nil
var rc: Int32

    // decryption code
    
   let databasePath_NewFile = Util.getPath("demo.sqlite")
    
    let newDstPath11 = String(format: "%@/Documents/encrypted1.sqlite",NSHomeDirectory())
    
    let newFullDestPath = NSURL(fileURLWithPath: newDstPath11)
    let newDstPath = newFullDestPath.path
    
    
    
    // first open encrypted database
    if (sqlite3_open(newDstPath11, &db) == SQLITE_OK) {
        
        print("Database open successfully.")
       
        let result = sqlite3_exec(db, "PRAGMA key = 'ganesh';", nil, nil, nil);
        print("Result: ", result)
        
        
        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)")
        }
        
        
        /*
         sqlite> PRAGMA key = 'testkey';
         sqlite> ATTACH DATABASE 'plaintext.db' AS plaintext KEY '';  -- empty key will disable encryption
         sqlite> SELECT sqlcipher_export('plaintext');
         sqlite> DETACH DATABASE plaintext;
         */
        
        
        let newQuery1 = "ATTACH DATABASE '\(newDstPath11)' AS plaintext KEY '';"
        print("NewQuery: ", newQuery1)
        
        if sqlite3_exec(db, newQuery1, nil, nil, nil) == SQLITE_OK {
            
            if sqlite3_exec(db, "SELECT sqlcipher_export('plaintext');", nil, nil, nil) == SQLITE_OK{
                
                
                if sqlite3_exec(db, "DETACH DATABASE plaintext;", nil, nil, nil) == SQLITE_OK{
                    
                    print("Everything ok:")
                    
                    
                }else{
                    
                    
                    let errmsg = String(cString: sqlite3_errmsg(db))
                    NSLog("DETACH DATABASE encrypted: \(errmsg)")
                }
                
                
            }else{
                let errmsg = String(cString: sqlite3_errmsg(db))
                NSLog("Error sqlcipher_export: \(errmsg)")
            }
            
        }else{
            
            let errmsg = String(cString: sqlite3_errmsg(db))
            NSLog("Error opening database: \(errmsg)")
            
        }
        
    }

///// it gives error like
Database open successfully.
Result: 0
NewQuery: ATTACH DATABASE ‘/var/mobile/Containers/Data/Application/9D4EA875-1F99-4642-AFC3-DE5E69F4B47D/Documents/encrypted1.sqlite’ AS plaintext KEY ‘’;
2017-11-28 10:29:32.604385+0530 SQLCipherDemo_21nov[4365:2318614] Error opening database: file is encrypted or is not a database

please help me.


#2

@Ganesh_Padole

Your sqlcipher_export() encrypted database location

is the same as your sqlcipher_export() unencrypted database location

So when you attempt to Attach the database that’s already encrypted with a passphrase here using no key:

it’s not going to work as that database is already encrypted, which is why you’re receiving that error message

Changing your newDstPath11 to something else like

let newDstPath11 = String(format: "%@/Documents/plaintext1.sqlite",NSHomeDirectory())

will most likely resolve your immediate issue. But you may want to re-think your design.

What is it that you’re attempting to accomplish? Usually the sqlcipher_export() convenience function is used for migrating an un-ecrypted sqlite database to an encrypted sqlcipher database or vice-versa. Most of the time you’ll only need to be doing this once, after-which you can open the db and key it using the sqlite3_key() then perform standard selects/inserts/updates/deletes on the database.


#3

i changed the path as mentioned but it is not working it gives error like database plaintext is already in use


#4

Actually my task is create new encrypted database file decrypt that encrypted database file .
i am creating encrypted database file in document directory and using same encrypted database file from document directory to decrypt that file , but it is not working.please help me.

This is Import/Export database functionality.


#5

@Ganesh_Padole

You’re going to need two separate paths:

  1. The current encrypted database path that you’re going to need to sqlite3_open and key.
  2. The plain text database path that’s going to be used for sqlcipher_export() for migrating from your encrypted database to plain text.

Currently both of these are are using the same path:

So why don’t we rename this one to be a little clearer:

let encryptedDbPath = String(format: "%@/Documents/encrypted1.sqlite",NSHomeDirectory())

And create another path for the output plain text db

let plaintextDbPath = String(format: "%@/Documents/plaintext1.sqlite",NSHomeDirectory())

Now when opening you’re going to want to use the encrypted db path:

// first open encrypted database
    if (sqlite3_open(encryptedDbPath, &db) == SQLITE_OK) {
...

but then when attaching the plaintext db to be exported you’re going to want to use the plain text db path:

let newQuery1 = "ATTACH DATABASE '\(plaintextDbPath)' AS plaintext KEY '';"

Let me know if this resolves the issue for you.

Cheers,
Micah


Unable to encrypt database in swift 3
#6

Thanks,
It works perfectly.