Alex, thanks:
On 2014-10-29 08:59 AM, David Arturo Macias Corona wrote:
>> How to encrypt DBF/CDX files with memo type fields ?
>Alex Strickland: Ah, sorry, I don't use memo fields. You'll have to see what Przemyslaw
>has to say.
I want to encrypt DBF files with memo type fields, in Linux
My first tests were made in October 2014 with help of Alex Strickland sample
Everything stopped due Harbour does not encrypt DBF files when memo file is used
In december 2014 I made tests with Harbour without and with ADS/win
Summary:
//Test 1: without MEMO field Work
//Test 2: with MEMO field Fail
//Test 3: with MEMO field, ADS Work
It work with Harbour+ADS+Win, and maybe with Harbour+ADS+Linux
But I do not want ADS in Linux, I want native DBFCDX in Linux
Source for tests are included below, with some notes about differences between ADS 6.2x and ADS 7.x
and greater, related to encryption
Basically,
for ADS 6.2x: encrypt DBF file, but not memo file
for ADS 7.x and greater: encrypt everything
--------------------------------------------
All fields in the table, including memo and BLOB fields, are encrypted
[...]
Note Any DBF table containing a memo or BLOB field that is encrypted with Advantage 7.0 or greater
will no longer be compatible with previous versions of Advantage.
--------------------------------------------
Some weeks ago I made an review of src/rdd/dbf1.c
It contain this note:
-------------------------
/* at this moment only one encryption method is used,
I'll add other later, [druzus] */
pArea->bCryptType = DB_CRYPT_SIX;
-------------------------
and is plenty of code like this:
-----------------------
fSet = ! pArea->fHasMemo && HB_IS_STRING( pPasswd ) && ( ! fRaw || nLen == 8 );
... && ! pArea->fHasMemo ...
pArea->fEncrypted = pArea->pCryptKey != NULL && ! pArea->fHasMemo;
...
if( ! pArea->fHasMemo )
pArea->fEncrypted = HB_TRUE;
-----------------------
so if "pArea->fHasMemo" is true, encryption is ignored :-)
Looking deeply in ChangeLog I found this:
-----------------------
2007-09-25 03:20 UTC+0200 Przemyslaw Czerpak (druzus/at/
priv.onet.pl)
* harbour/include/hbset.h
[...]
I still do not allow to encrypt tables with memo fields to not
replicate SIx3 bugs which may cause data corruption.
-----------------------
Previous note clarify everything:
Harbour does not allow encrypt DBF with Memo files to prevent data corruption
It does it "by design"
Przemek:
Near 8 years later:
- There are some possibilities to encrypt DBF files with memo files, without data corruption, of
course ?
- and/or, any other alternatives ?
David Macias
#include "
dbinfo.ch"
request dbfcdx
request ADS
procedure main()
local aStruct := { ;
{ "Name", "C", 20, 0 }, ;
{ "Age", "N", 3, 0 }, ;
{ "Boy", "L", 1, 0 }, ;
{ "Birth", "D", 8, 0 } ;
}
//Test 1: without MEMO field
rddsetdefault("DBFCDX")
dbcreate("dbcrypt", aStruct)
use dbcrypt
dbcrypt->( dbappend() )
dbcrypt->name := "Fred"
dbcrypt->age := 20
dbcrypt->boy := .t.
dbcrypt->birth := date() - (20 * 365)
?
? "Test 1"
? "DBI_ENCRYPT - barneyrubble", dbcrypt->( dbinfo( DBI_ENCRYPT,"barneyrubble" ) )
? "DBI_ISENCRYPTED", dbcrypt->( dbinfo( DBI_ISENCRYPTED ) )
?
dbcrypt->( dbclosearea() )
//Test 2: with MEMO field
AADD( aStruct, { "MyMemo", "M", 10, 0 } )
rddsetdefault("DBFCDX")
dbcreate("dbcrypt2", aStruct)
use dbcrypt2
dbcrypt2->( dbappend() )
dbcrypt2->name := "Fred"
dbcrypt2->age := 20
dbcrypt2->boy := .t.
dbcrypt2->birth := date() - (20 * 365)
dbcrypt2->mymemo := "My MEMO field content"
?
? "Test 2"
? "DBI_ENCRYPT - barneyrubble", dbcrypt2->( dbinfo( DBI_ENCRYPT,"barneyrubble" ) )
? "DBI_ISENCRYPTED", dbcrypt2->( dbinfo( DBI_ISENCRYPTED ) )
?
dbcrypt2->( dbclosearea() )
//Test 3: with MEMO field, ADS
AdsSetServerType( 2 )
rddSetDefault( "ADSCDX" )
dbcreate("dbcrypt3", aStruct)
use dbcrypt3
dbcrypt3->( dbappend() )
dbcrypt3->name := "Fred"
dbcrypt3->age := 20
dbcrypt3->boy := .t.
dbcrypt3->birth := date() - (20 * 365)
dbcrypt3->mymemo := "My MEMO field content"
?
? "Test 3"
? "ADSENABLEENCRYPTION() - barneyrubble", dbcrypt3->( ADSENABLEENCRYPTION( "barneyrubble" ) )
? "ADSENCRYPTTABLE()", dbcrypt3->( ADSENCRYPTTABLE() )
? "ADSISTABLEENCRYPTED()", dbcrypt3->( ADSISTABLEENCRYPTED() )
?
dbcrypt3->( dbclosearea() )
return
/*
ads8
AdsEncryptTable encrypts all the records in a table with the current password set via
AdsEnableEncryption. All fields in the table, including memo and BLOB fields, are encrypted when
this function is used. This function requires exclusive use of the table. If records exist that are
already encrypted, they are ignored. An entire table can be decrypted by calling AdsDecryptTable.
Encrypting a table within a transaction is not allowed.
Note that with a DBF table, in addition to all records being encrypted, the header of a DBF table is
encrypted to prevent non-Advantage applications from opening the table.
Note AdsEncryptTable only accepts table handles. The use of a cursor handle with this API is
illegal and will result in an error. See AdsExecuteSQL for more details.
Note AdsEncryptTable is only applicable with free tables. The encryption process is done
automatically with database tables. ALTER permissions on the table are required to encrypt or
decrypt database tables. See Advantage Data Dictionary for more information.
Note Before encrypting a table, it is recommended that you pack the table first via AdsPackTable so
that previously deleted records are not left unencrypted.
Note Any DBF table containing a memo or BLOB field that is encrypted with Advantage 7.0 or greater
will no longer be compatible with previous versions of Advantage.
ads620
AdsEncryptTable encrypts all the records in a table with the current password set via
AdsEnableEncryption. This function requires exclusive use of the table. If records exist that are
already encrypted, they are ignored. An entire table can be decrypted by calling AdsDecryptTable.
Encrypting a table within a transaction is not allowed.
Note that with a DBF table, in addition to all records being encrypted, the header of a DBF table is
encrypted to prevent non-Advantage applications from opening the table.
Note AdsEncryptTable only accepts table handles. The use of a cursor handle with this API is illegal
and will result in an error. See AdsExecuteSQL for more details.
Note AdsEncryptTable is only applicable with free tables. The encryption process is done
automatically with database tables. Data dictionary administrative access is required to encrypt or
decrypt database tables. See Advantage Data Dictionary for more information.
Note Before encrypting an ADT table, it is recommended that you pack the table first via
AdsPackTable so that previously deleted records are not left unencrypted.
*/