You are not logged in.
Do you think there will be hope to implement encryption of individual database? If yes, is there a ETA? (I don't know your roadmap).
Offline
ab,
Is it possible to statically link with WxSqlite and use the encryption implemented be Wxsqlite? - just an idea.
Offline
WxSQlite is just a wrapper around the official SQLite3 library.
It includes only encryption for the non free SQLite Encryption Extension (SEE) module - http://www.hwaci.com/sw/sqlite/see.html
The link http://wxforum.shadonet.com/viewtopic.php?t=27217 did not work for me.
Offline
It is not a wrapper over hwaci SEE but over standard SQlite with added encryption. My understanding is it is a standalone implementation of encryption. However it is compatible with Hwaci implement.
I have used the dll with ZeosDB successfully.
Offline
Offline
It is not a wrapper over hwaci SEE but over standard SQlite with added encryption. My understanding is it is a standalone implementation of encryption. However it is compatible with Hwaci implement.
You are right: I did only check the official wxsqlite source code repository, whereas I should have checked in wxCode project.
I'll see what can be done with this code.
Offline
I've commited some test about per-database encryption.
See TTestExternalDatabase.CryptedDatabase in SynSelfTests.pas.
According to these tests, the per-database process is working as expected.
As expected, the testpass.db3-wal file is not encrypted, but the main testpass.db3 file is (after the first 1024 bytes).
In the tests, I add more than 11,000 rows of data to a file, close it.
testpass.db3 is encrypted as expected.
Then I open testpass.db3, and read the rows and check their content.
Then a row is added.
The whole testpass.db3 content is retrieved again, and checked again.
Then the testpass.db3 is uncrypted using ChangeSQLEncryptTablePassWord.
And the whole .db3 content is retrieved again, and checked again.
Current implementation sounds fine to me.
Encrypted file can be sometimes opened in SQLite3 standard tools, but the content is not available.
Offline
Sorry but this is not correct for me.
After use the single file encrypt, close the file and open it with a SQLite editor (I use this free tool http://sqliteadmin.orbmu2k.de/) I can see ALL the data: both database structure and record text, it's all clear. In this moment I'm not at home, this evining I will try again.
Can you write a small piece of code about an essential "single file" encrypt? (I think the code inside the test file is complex).
Last edited by array81 (2011-10-17 15:51:40)
Offline
It works for me.
This time even though testpass.db3 opens in sqlite3 browser, even the database structure is not visible.
Array, have you removed the old synopse directories from delphi library options?
Offline
Is it available to TSQLDBSQLite3ConnectionProperties.Create?
Offline
I was wrong.
even though sqlite browser does not list data, sqlite console shows the table and data - except that PC's bell is ringing throughout the listing.
Offline
Near the end of the test, the encryption is removed.
Try adding this line to the end of TTestExternalDatabase.CryptedDatabase; :
ChangeSQLEncryptTablePassWord('testpass.db3', '', password);
Offline
Is it available to TSQLDBSQLite3ConnectionProperties.Create?
No, it is not yet.
And is was never documented as such, in fact the creator description tells it explicitely: "other parameters (DataBaseName, UserID, Password) are ignored".
I was not sure it was all working as expected.
So I did not include it in SynDBSQLite3 unit yet.
Perhaps in release 1.16.
If it is found stable enough.
Offline
Near the end of the test, the encryption is removed.
You are perfectly right: as I wrote above, it is part of the testing method.
It is written with encryption, then the database file is globaly uncyphered with ChangeSQLEncryptTablePassWord.
So the remaining file on disk after test is plain and not encrypted.
But it you do not execute ChangeSQLEncryptTablePassWord, the database file will stay encrypted. You may be able to see some content (e.g. the table layout), but the content itself will be definitively encrypted.
Offline
OK, so it possible I don't have understand how it works.
In my case I just have an database file (this is an clear file, NO encrypth) and I want encryph it. This is my code:
try
Database := TSQLRestClientDB.Create(Model, nil, DBFileName, TSQLRestServerDB, False, edtPassword.Text);
try
finally
Database.Free;
end;
except
// error message
end;
DBFileName is the name of the database, edtPassword.Text is the password (I use a TEdit to write the password).
After this code the database is clear.
Are there error on my code?
Last edited by array81 (2011-10-17 21:09:37)
Offline
You should use ChangeSQLEncryptTablePassWord before you connect with the database
ChangeSQLEncryptTablePassWord(DBFilename, '', edtPassword.Text);
Offline
You should use ChangeSQLEncryptTablePassWord before you connect with the database
ChangeSQLEncryptTablePassWord(DBFilename, '', edtPassword.Text);
Indeed.
As stated by the documentation, and as shown in the test method supplied, it will encrypt the whole file at once, just as you need.
Offline
OK, I think now it works but I have a problem. I need know if I database is or not encryph (before open it). In fact if it encryph my application must ask the password.
I use this code IsSQLite3File(Filename), however this fuction return TRUE also with encryph database.
Is there a way to know if a database is encrypt or not?
Offline
The first page (i.e. first 1024 bytes) of the database are uncrypted, but other content is.
Is there a way to know if a database is encrypt or not?
There was not.
I've added this function in SynSQLite3.pas:
/// check if sounds like an encrypted SQLite3 file
// - this will check the 2nd file page beginning to be a valid B-TREE page
// - in some cases, may return false negatives (depending on the password used)
function IsSQLite3FileEncrypted(const FileName: TFileName): boolean;
Offline
Thanks, I will try it.
If I understand I can use IsSQLite3File function to know if the file is a SQLite file (both encryph and decrypt) and IsSQLite3FileEncrypted to know if the database is encryph (used after IsSQLite3File).
On your comment I see "in some cases, may return false negatives (depending on the password used)", what does it mean? When the password is a problem?
Offline
On your comment I see "in some cases, may return false negatives (depending on the password used)", what does it mean? When the password is a problem?
Only one byte is checked to be either 5, 10 or 13.
There may be some password content that may return such a value.
So it is not 100% sure.
Offline
I have a question, I think a stupid question but I cannot solve it.
I use this code:
try
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB, False, decrypt);
except
MessageDlg('ERROR', mtInformation, [mbOK], 0);
Exit;
end;
to open an encrypt file. I use try...except because I want capture the bad password error.
However, if I use the right password all works without problem, if I use a bad password I have only an exception inside Delphi (line 4001 of SynSQLite3 of last framework relaese) but outsite Delphi nothing.
I don't understand why my error message is not show.
Offline
I don't understand why my error message is not show.
In fact, the database opening probably only use the first page of the file, i.e. the uncrypted one.
So opening may always be correct, even with a wrong password.
Just call a simple SELECT on a table and it will fail in case of invalid password.
Any other method will probably encourage very easy "brute force" password cracking.
Offline
Are you implementing the new encryption on to TSQLDBSQLite3ConnectionProperties.Create?
Any plans to link with Wxsqlite?
Offline
Are you implementing the new encryption on to TSQLDBSQLite3ConnectionProperties.Create?
It is already the case.
See http://synopse.info/fossil/fdiff?v1=294 … ef20d53de0
Any plans to link with Wxsqlite?
If the current version works, there is no need to use the wxsqlite implementation, which is more complex to integrate.
Offline
It is already the case.
Thanks, tested - OK.
If the current version works, there is no need to use the wxsqlite implementation, which is more complex to integrate.
The advantage I see is that the resultant database will be compatible with other implementations, and that it camouflages the fact that the file is a sqlite database.
If I decrypt an encrypted database, the file seems to be not fully sqlite compatible. sqlite browser cannot open the file. sqlite console will read the file, but will keep the PC bell ringing.
Offline
I'm using the static SQLite3 wrapper (i.e. away from mORMot) and just wanted to check I'm using encryption correctly in the following code snippet...
procedure TForm1.connectButtonClick(Sender: TObject);
var
conn: TSQLDBSQLite3ConnectionProperties;
dbFilename: String;
rows: Variant;
begin
dbFilename := 'C:\Temp\bds';
ChangeSQLEncryptTablePassword(dbFilename, '123', ''); // unencrypt tables
conn := TSQLDBSQLite3ConnectionProperties.Create(dbFilename, '', '', '');
try
with conn.Execute('SELECT * FROM TableName', [], @rows) do
begin
while Step do
ShowMessage(rows.Id + ': ' + rows.Description);
end;
finally
FreeAndNil(conn);
end;
ChangeSQLEncryptTablePassword(dbFilename, '', '123'); // re-encrypt tables
end;
...or is there a better way?
By the way, it seems that CreateSQLEncryptTable isn't available as a public method in SynSQLite3Static.pas.
Any advice would be much appreciated.
Last edited by w5m (2014-11-13 14:55:48)
Offline
What do you want to do?
Here you are decrypting then encrypting the whole file before use.
IMHO this is not what encryption is for.
To use encryption, just specify the password to TSQLDBSQLite3ConnectionProperties.Create() !
Then the file will stay encrypted on disk, as expected.
Note that you are using a TSQLDBSQLite3ConnectionProperties instance locally, together with an Execute() method which will return an hidden interface instance.
This is not correct, regarding how Delphi works.
Offline
Thanks for the quick response Arnaud.
What I'm trying to do is protect a dataset such that it cannot be browsed. I thought I had to unencrypt the database in order to query it, then re-encrypt it so that it remains unbrowsable by others.
Are you saying that I can throw away my calls to ChangeSQLEncryptTablePassword and instead pass the password as the 4th parameter of TSQLDBSQLite3ConnectionProperties.Create()? If so, does that mean the database needs to have been previously encrypted? If so, how?
You mentioned I'm not using the correct approach by using a TSQLDBSQLite3ConnectionProperties instance locally and the Execute method. What is the correct approach?
Apologies if I'm asking basic questions, but I'm very new to both SQLite and your units.
Any advice would be much appreciated.
Offline
Excellent - thanks for confirming Arnaud. I've got the encryption sorted now.
I found another of your posts which gave an example of how to structure the rest of the code correctly...
http://synopse.info/forum/viewtopic.php?pid=9397#p9397
Many thanks!
Offline
Yes, the best is perhaps to maintain a TSQLConnectionProperties instance for the whole application.
It will feature some nice thinks like a faster re-use of an existing connection, statement cache, and per-thread connection, if needed.
Offline