# Can't open an encrypted database in C

**URL:** <https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230>\
**Category:** SQLCipher\
**Created:** [December 29, 2021, 1:38pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230 "2021-12-29T13:38:25Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [December 29, 2021, 1:38pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/1 "2021-12-29T13:38:25Z")

</div>

Simply i have an encrypted database, and my code should filter out the key from a text file.  
i’ve done all that, but when i run my code it says “file is not a database”.

After lots of reserch i beleive the problem wil be in how the ‘key’/‘password’ generated from the text file are encoded.

beacuse passing the key manully using sqlcipher from the command line decrypt the databse and opens it, works fine!

What i’ve done:

Opening the database file :

` int rc = sqlite3_open("/path/to/database.sqlite", &db);`

Storing the PRAGMA statment for setting the key in a variable to use it :

`snprintf(keyQ, sizeof(keyQ), "PRAGMA key=\"x'%s'\";", subbuff);`

knowing that the variable `subbuff` is actully the key as a char array.

Setting the `sqlite3_exec` calls:

`rc = sqlite3_exec(db,keyQ, NULL, 0, NULL);`

`rc = sqlite3_exec(db, "PRAGMA cipher_plaintext_header_size = 32;", 0, 0, NULL);`

`rc = sqlite3_exec(db, "PRAGMA cipher_compatibility = 3;", 0, 0, NULL);`

knowing that the error occurs only when i pass in an actual qurery like the following:

`char *sql = "SELECT * FROM table;";`  
` rc = sqlite3_exec(db, sql, callback , 0, &errMsg);`  
if i comment the last line, no error happen.

i’ve tried lots and lots of solutions without any results.  
please help ☹

---

<div class="post-metadata">

**Author:** ![sjlombardo](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/sjlombardo/32/3_2.png) [@sjlombardo](https://discuss.zetetic.net/u/sjlombardo)\
**Post date:** [December 29, 2021, 4:59pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/2 "2021-12-29T16:59:07Z")

</div>

The problem may be that you are using `cipher_plaintext_header_size`. That PRAGMA allocates an unencrypted portion at the start of the database some of which is where the salt would normally be stored. You would need to use `PRAGMA cipher_salt` to ensure that the salt is configured correctly as well. Please review the documentation for [PRAGMA cipher\_plaintext\_header\_size](https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_plaintext_header_size) for details.

---

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [January 2, 2022, 10:09am UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/3 "2022-01-02T10:09:09Z")

</div>

Thank you so much for the quick response  
I did add `PRAGMA cipher_salt = "x'01010101010101010101010101010101'";`  
same error : file is not a database

---

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [January 3, 2022, 10:17am UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/4 "2022-01-03T10:17:53Z")

</div>

could it be that the password are actually changed after being encoded? cuz the error “file is not a database” will occurr when the key is wrong.  
the key is a char array containg the right key.

---

<div class="post-metadata">

**Author:** ![sjlombardo](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/sjlombardo/32/3_2.png) [@sjlombardo](https://discuss.zetetic.net/u/sjlombardo)\
**Post date:** [January 3, 2022, 3:39pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/5 "2022-01-03T15:39:49Z")

</div>

The Password on a database can’t change after it is created without using `PRAGMA rekey`. However, you are storing / retriving the key material from. If that value changes it would be unable top open the database. Also, make sure you are creating the databse from scratch the first time (i.e. that database.sqlite does not already exist).

Without additional information I’m not sure what else could be amiss here, but it is very likely a problem with the application logic. If you can produce a small standalone app that reproduces the problem it might be helpful for troublshooting.

---

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [January 4, 2022, 12:14pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/6 "2022-01-04T12:14:03Z")

</div>

Thanks again for the reply, here’s a demonstration of what i’m facing:

```auto
extern char **environ;
char fString[2000];

int callback(void *, int, char **, char** );

int callback(void *NotUsed, int argc, char **argv, char** colName) {
    char buff[7000];
    for (int i = 0; i < argc; i++) {
        snprintf(buff, sizeof(buff), "%s = %s \n ", colName[i], argv[i]);
        strcat(fString, buff);
    }
    strcat(fString, "@--------@\n");
    return 0;
}

int main () {
    sqlite3 *db;
    char *errMsg = 0;
    
    int rc = sqlite3_open("/path/to/encrypted/db.sqlite", &db);
    
    rc = sqlite3_key(db, "0f9424100af49c8c1ce0d2c79b2958f67d9f4aa056b1c216ed82171e41c1310966d65af32844bc2974b5a7788cb90f38", strlen("0f9424100af49c8c1ce0d2c79b2958f67d9f4aa056b1c216ed82171e41c1310966d65af32844bc2974b5a7788cb90f38"));
    
// error not occure here 
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Error in key --- %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }

/*
 The following lines are the another approch for giving the key as PRAGMA statment. 
eather way it failed with same error message.
*/

// rc = sqlite3_exec(db,"PRAGMA key=\"x'0f9424100af49c8c1ce0d2c79b2958f67d9f4aa056b1c216ed82171e41c1310966d65af32844bc2974b5a7788cb90f38'\";", 0, 0, NULL);
// rc = sqlite3_exec(db, "PRAGMA cipher_plaintext_header_size = 32;", callback, 0, NULL);
// rc = sqlite3_exec(db, "PRAGMA cipher_salt = \"x'01010101010101010101010101010101'\";", callback, 0, NULL);
// rc = sqlite3_exec(db, "PRAGMA cipher_compatibility = 3;", callback, 0, NULL);
    
    char *sql = "SELECT * FROM table;";
    
    rc = sqlite3_exec(db, sql, callback , 0, &errMsg);
    
// The error happen here
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Error opening the database --- %s\n", sqlite3_errmsg(db));
        sqlite3_close(db); // <- will return 
        return 1;
    }
    sqlite3_close(db);
    return 0;
}

```

Sorry for the inconvenience…

knowing that performing the PRAGMA statments using sqlcipher tool from the command line works perfectly with the same database and password.

---

<div class="post-metadata">

**Author:** ![sjlombardo](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/sjlombardo/32/3_2.png) [@sjlombardo](https://discuss.zetetic.net/u/sjlombardo)\
**Post date:** [January 5, 2022, 2:27pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/7 "2022-01-05T14:27:24Z")

</div>

In the example you are referencing, does db.sqlite already exist? Is it a plaintext SQLite database?

---

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [January 6, 2022, 9:51am UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/8 "2022-01-06T09:51:58Z")

</div>

yes it already exist, and it’s a plaintext database.  
the ‘key’ for the database is given as a plaintext in sqlite3\_key() function.

---

<div class="post-metadata">

**Author:** ![sjlombardo](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/sjlombardo/32/3_2.png) [@sjlombardo](https://discuss.zetetic.net/u/sjlombardo)\
**Post date:** [January 6, 2022, 8:55pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/9 "2022-01-06T20:55:12Z")

</div>

The problem is that `sqlite3_key` will not encrypt an existing plaintext database. You will need to use a migration method:

[SQLCipher API - Zetetic](https://www.zetetic.net/sqlcipher/sqlcipher-api/#sqlcipher_export)

---

<div class="post-metadata">

**Author:** ![mjeed](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/mjeed/32/1738_2.png) [@mjeed](https://discuss.zetetic.net/u/mjeed)\
**Post date:** [January 10, 2022, 8:48am UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/10 "2022-01-10T08:48:14Z")

</div>

Thanks for all your help, i might not explaining the problem that i’m facing correctly :

the database (sqlite file) is already exist, and it is an encrypted database.

and i have the key for the database, and according to your post [here](https://discuss.zetetic.net/t/how-to-encrypt-a-plaintext-sqlite-database-to-use-sqlcipher-and-avoid-file-is-encrypted-or-is-not-a-database-errors/868)

> The same process also works in reverse to create a plaintext, fully decrypted, copy of an encrypted SQLCipher database that can be opened with standard SQLite.

```auto
$ ./sqlcipher encrypted.db
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;

```

I implement the same:  
after `int rc = sqlite3_open()`

```auto
rc = sqlite3_exec(db, "PRAGMA key=\"x'theKeyForDB'\";", NULL, NULL, &errMsg);
rc = sqlite3_exec(db, "ATTACH DATABASE 'plaintext.sqlite' AS plaintext KEY '';", NULL, NULL, &errMsg);
rc = sqlite3_exec(db, "SELECT sqlcipher_export('plaintext');", NULL, NULL, &errMsg);
rc = sqlite3_exec(db, "DETACH DATABASE plaintext;", NULL, NULL, &errMsg);

```

And this is the error messages that i got after each sqlite3\_exec():

```auto
attach error: file is not a database
export funciton error: no such function: sqlcipher_export
cant perform query: file is not a database

```

The database that i want to decrypt is signal application database in ios, using the CLS for sqlcipher works perfect.

---

<div class="post-metadata">

**Author:** ![sjlombardo](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.zetetic.net/sjlombardo/32/3_2.png) [@sjlombardo](https://discuss.zetetic.net/u/sjlombardo)\
**Post date:** [January 10, 2022, 2:06pm UTC](https://discuss.zetetic.net/t/cant-open-an-encrypted-database-in-c/5230/11 "2022-01-10T14:06:08Z")

</div>

Hello @mjeed - thanks for getting back with these additional details and explanation. To recap, you are trying to open a preexisting encrypted database created using Signal with a known key. I think it would be worthwhile to determine if your application is actually properly linking SQLCipher. Can you please execute the following in the application and capture the value from the result set?

```auto
PRAGMA cipher_version;

```

This should report the SQLCipher version. If there is no result set then SQLCipher is not properly linked. If a version is returned, you should compare it against the version returned from the command like SQLCipher you’ve been able to use to successfully open the database to make sure they have the same major version number.
