Re: DBF encrypted

557 views
Skip to first unread message

David Arturo Macias Corona

unread,
Apr 22, 2015, 3:53:27 AM4/22/15
to harbou...@googlegroups.com
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.

*/



Qatan

unread,
Apr 22, 2015, 5:12:17 AM4/22/15
to harbou...@googlegroups.com
Hello,
 
If you allow me to just suggest an idea:
 
I think you can change a switch to allow DBF with MEMO to be encrypted but not the MEMO itself.
“DBI_ENCRYPT”
How/Where to do it you can find searching on the Changelog and on the previous discussions.
To encrypt the MEMO just use MD5 or Blowfish encryption functions to and than you have a complete solution in your system
To find it just do the same again (search). I tested those encryption functions and they work very well:
 
2012-09-13 16:02 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
  * harbour/src/rtl/hbbffnc.c
  * harbour/include/harbour.hbx
    + added new functions for BlowFish encryption using CFB (cipher feedback)
      mode instead of ECB (electronic codebook) mode with ANSI X.923 padding:
         hb_blowfishEncrypt_CFB( <cBfKey>, <cText> [, <cInitSeed> ] )
                  -> <cCipher> | NIL
            return string encrypted using CFB (cipher feedback) mode or
            NIL on error (wrong parameters)
         hb_blowfishDecrypt_CFB( <cBfKey>, <cCipher> [, <cInitSeed> ] )
                  -> <cText> | NIL
            return string decrypted using CFB (cipher feedback) mode or
            NIL on error (wrong parameters),
 
  * harbour/src/rtl/Makefile
  + harbour/src/rtl/hbmd5enc.c
  * harbour/include/harbour.hbx
    + added new functions for MD5 encryption/decryption
      using CFB (cipher feedback) mode:
         hb_MD5Encrypt( <cText>, <cPasswd> ) -> <cCipher>
         hb_MD5Decrypt( <cCipher>, <cPasswd> ] ) -> <cText>
 
 
Please look also these Chagelog entries:
 
2015-02-08 13:19 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
  * src/rdd/workarea.c
    + added support for field flags in dbCreate()/dbStruct().
      Flags can be passed in string with field type after ":", i.e.
         "C:U"
      means Unicode character field.
      The following flags are recognized:
         "N" - column can store null values
         "B" - binary column
         "+" - column is autoincrementing
         "Z" - column is compressed
         "E" - column is encrypted
         "U" - column stores Unicode strings
 
 
 
2011-02-03 12:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
  * harbour/src/rdd/dbf1.c
    ! fixed DBI_ENCRYPT to use previously set password if no new one
      is given
 
  * harbour/src/rdd/hbsix/sxtable.c
    ! fixed wrong parameter checking in SX_SETPASS()
    ! removed wrong comment about optional parameter in SX_DBFENCRYPT()
 
  * harbour/src/vm/cmdarg.c
    ! added missing OS CP conversion in HB_ARGV()
 
  * harbour/contrib/hbct/ctmisc.prg
    * use HB_PROGNAME() instead of HB_ARGV( 0 ) in EXENAME()
 
  * harbour/contrib/hbnetio/readme.txt
    ! fixed two typos in description
 
and etc...
 
Qatan
--
You received this message because you are subscribed to the Google Groups "Harbour Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-deve...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages