FireDAC SQLite Standard Encryption question - sqlite

If I declare and create some SQLite database inside FDConnectionDefs.ini as follows
[SQLITESAMPLE]
Database=sample.sdb
Password=masterkey
LockingMode=Normal
SharedCache=false;
DriverID=SQLite
it should be encrypted with aes-256 as standard settings. FDSQLiteSecurity1.CheckEncryption is returning aes-256
Later, if I add the param Encrypt=aes-256 to that definition my apps still work correctly.
But RAD Studio Data Explorer and FireDAC Explorer will only work with a setting
Encrypt=No(with aes-256 I get some corrupt datafile message from these two apps).
If I define the Encrypt=aes-256 param from the beginning all apps do work correct.
Maybe there is some other encryption mode standard defined, if I do not declare encryption mode from the beginning? I wonder about this.

The SQLite3 DB file is either encrypted, or not, from the beginning.
You will have to maunally backup the file from one encrypted state to another.
There is no "standard" free encryption on SQLite3.
Only a few variants:
FireDAC encryption
Closed Source SQLite Encryption Extension
SQLite-Crypt commercial
SQLCipher
WXSQLite3 variant
DISQLite3 commercial for Delphi
SynSQLite3 Delphi/FPC Open Source
and probably others... all incompatible!

Related

Encrypt SQLITE database and use it with FireDac in a windows VCL application

I am writing a Windows VCL desktop using c++ builder. The app uses Firedac and a SQLite database.
I want to protect this SQLite database:
Only my vcl app can connect to it and use it
Other programs and people cannot use the SQLite file
So far I found that the easiest thing that I can do is Encryption, you make it so that anybody without a correct password gets a message like "This file is not a database" if he tries to open it.
Yes we can do this with Embarcadero VCL, doc. using a TFDSQLiteSecurity component and these lines :
FDSQLiteSecurity1->Password = "";/* we are protecting (encrypting) our uncyphered database*/
FDSQLiteSecurity1->ToPassword = 'newpassword';
FDSQLiteSecurity1->ChangePassword();
Unfortunately the VCL Firedac app cannot connect to an encrypted sqlite database so it must decrypt it first.
In order to make things work my program starts and decrypts the database ( removes password) then it connects to the database and use it. When finished I recrypt the database again (when closing app).
THE PROBLEM:
During this time (My program is up and running and the database in uncrypted) can I stop other programs from opening the SQLITE database? Is there a better approach, I am opened for any suggestion
Once it is encrypted by FireDac just set the appropriate properties on the FDConnection. Those would be password to the password and encrypt to the encryption method.
Firedac can open a SQLite database it has encrypted itself so the problem resolves itself by doing that as a better approach. Other programs only see the encrypted version on disk and can't open it without the password.

How encrypt SQLite database with FireDAC?

I'm create SQLite databse with DB Browser for SQLite (non encrypted) and open with FireDAC in delphi.(Can retrive data Eg. Select * from abc).
How encrypt this SQLite database with FireDAC? When enter username, password and encrypt get message "Cipher DB is not encrypdet"
Note:
When create SQLite database from Delphi FireDac I can use encryption!
To encrypt a database, use a TFDSQLiteSecurity Component. You'll also need a TFDSQLitePhysSQLiteDriverLink component to go along with it.
If a database is unencrypted, then its password is ''. So use '' as the OldPassword and create the new password in that case. Passwords are formatted as algorithm:PassPhrase. See documentation on the choices, I use aes-256. Also, the database needs to be closed when you do this.
...
//Change password
FDSQLiteSecurity1.Password := OldPassword;
FDSQLiteSecurity1.ToPassword := NewPassword; // example: 'aes-256:mypassword123'
FDSQLiteSecurity1.ChangePassword;
...
//Remove Password
FDSQLiteSecurity1.Password := OldPassword;
FDSQLiteSecurity1.ToPassword := '';
FDSQLiteSecurity1.RemovePassword;
...
From the Documentation
SQLite Encrypted Database
Approach
One of the distinctive SQLite
features is the high-speed strong database encryption. It allows you
to make database file content confidential and enforce integrity
control on the database file. The encrypted database format is not
compatible with other similar SQLite encryption extensions. This means
that you cannot use an encrypted database, encrypted with non-FireDAC
libraries. If you need to do this, then you have to decrypt a database
with an original tool and encrypt it with FireDAC.
Recent Delphi versions come with an example project for working with encryption on Sqlite databases, see this documentation. I have not used this myself, btw.
It includes this section
Encrypt DB
Encrypt: Encrypts the database according to the Encryption mode and the password provided.
The sampe uses TFDSQLiteSecurity.SetPassword to encrypt the database with the password provided.
The database password is the combination of <encryption algorythm>:<password>.
I have faced several challenges when first time tried to encrypt SQLite database for use with Embarcadero FireDAC. Also all information is published by Embarcadero question pops up again and again on different forums. My case was solved based on community support, but when time has permitted simple Delphi application was assembled and available on Sourceforge. Hope it will make encryption/decryption slightly easier particularly for the newbie
https://sourceforge.net/projects/sqlite-sequrity-for-delphi/

'file is encrypted or is not a database' error while opening the sqlite db

I have a sqlite database in my UWP app. On the very first launch of my app, I create the database and set it up with all the tables and stuff. I play around with the app and generate some data just fine. But when I close and relaunch the app, it starts giving me 'file is encrypted or is not a database' error while trying to execute any query.
I am using sqlite3.dll v3.12.0 and here is my pragma key statement (with an example encryption key):
"PRAGMA key='aes256:66zk4rsKBIfSJ4vhF1XkzFxzrznOhjjnotuHRdKADIg='"
I verified, on second launch, the encryption key is being used to run the pragma key statement.
Edit: It looks like the encryption went just fine. Because, when I use a tool like SQLite Manager and provide the same key, it opens the db just fine.
I think what might be happening to you Is that you use to have a previous library of SQLite working with encryption working properly like I did.
<SDKReference Include="SQLite.UAP.2015, Version=3.10.2">
<Name>SQLite for Universal App Platform</Name>
</SDKReference>
And since you updated the library to v3.12.0 the PRAGMA key in this version did not work hence not being able to enter to the previous encrypted DB.
I'm trying to rebuild the link to that version but is hard: "SQLite.UAP.2015, Version=3.10.2"

Advantage of sqlcipher

I have a general question to sqlcipher.. where is the advantage of sqlcipher against directly encrypting the database with GnuPG or openssl?
Everytime when I want to encrypt/decrypt with sqlcipher I must open the database, attach a new database, encrypt/decrypt it, export it in the new database and deattach it. For example like this:
echo "PRAGMA key='$1';select count(*) from sqlite_master;ATTACH DATABASE '$2/mydb-decrypt.db' AS plaintext KEY '';SELECT sqlcipher_export('plaintext');DETACH DATABASE plaintext;" | sqlcipher $2/mydb.db
This is pretty bloated isn't it?
With openssl or gnupg I can just decrypt/encrypt it directly with one command..
so why using sqlcipher?
The conflict you are seeing is likely in how you are using it versus how it is more commonly used. SQLCipher decrypts and encrypts data on the fly for user access. That is to say that once you have provided SQLCipher with the key material, only the pages of data that contain your data are decrypted. This does not require you to decrypt the entire database to plain text and write to disk in order to access your data as you model above. I would recommend you review the additional details on the SQLCipher design here.

Thales HSM Generate key "Form key from clear components" ("FK" command)

I have two clear components, generated by command 000A30303030413230303255 (it's a 000A0000A2002U in HEX mode. This is "GC" - Translate a ZPK from LMK to ZMK Encryption command from 1270A513 Issue 3 manual) using Java code
Now I need to generate an Encrypted key from those components. The console command for it: "FK" command (1270A513 Issue 3, page 5-14).
I couldn't find any commands for doing it by Java code. I used Host Command Reference manual (1270A351 Issue 6) and found only A4- Form a Key from Encrypted Components command, but this command for generating key from Encrypted components.
Is there way to generate encrypted key using clear components?
There is no way to do this and for good reason. If you were to send this via your java code it is open to attack as the clear components are being sent through the network unencrypted. Any person intercepting these components can generate the key themselves. The GC and FK commands are meant to be used with the console and not remotely which is why it is possible using those commands.
If you already have the components you can only form them at the HSM console. If you can possibly generate new keys use the A0 command from your java code.
I don't recommend using this in production. I would take following steps if i really need to do that.
Generate A ZMK(clear and encrypted) on HSM console using 'GC' and 'FK' command.(Need to do only once and reuse key).
use clear ZMK to encrypt all of your keys using TripleDES-ECB-NOPADDING in your application.
Use command 'A6'. Import all ZMK encrypted keys to LMK.
Use 'A4' command to form key using LMK encrypted Components.

Resources