On Wed, 12 Sep 2012, Qatan wrote:
Hi,
> By the way, do you know it sx_DbfEncrypt() / sx_DbfDecrypt() uses blowfish?
> I belive it doesn’t (maybe because it should be compatible with Six?)
It uses the same encryption as sx_enCrypt() / sx_deCrypt().
This encryption uses 64bit seed to encode serialized bytes.
For sure it's much stronger then xor or other simple encryption
but in current days of very fast computers for sure cannot be
called save encryption and for sure it's not safe for good mathematician
even without computer (in 1932 Polish mathematicians broke Enigma
encryption without any electronic computers but Rejewski, Różycki
and Zygalski were geniuses who created whole new mathethical theory
which is still used).
> Anyway I found what Przemek wrote: “I still do not allow to encrypt tables
> with memo fields to not replicate Six3 bugs which may cause data corruption.”
This is problem with SIX3 implementation not encryption efficiency.
If you look at SIX3 encryption then you will find that you can encrypt/decrypt
single records. The problem is that in some cases only data in DBF is encrypted
but not in memo but the flag is set for whole record so on reading unencrypted
data from memo is deciphered giving wrong results. For some fields like
"V", 20, 0
Part of string is stored in DBF and the rest for longer strings in memo
file. Such fields after decoding are partially broken, etc.
To implement it well it's necessary do drop SIX3 compatibility and it was
the reason I leave it as is blocking encryption for tables with memos.
> (Changelog 2007-09-25 03:20 UTC+0200 Przemyslaw Czerpak) so no encryption for
> memo fields than I thought: “Why not use blowfish?” The answer is probably
> because of compatibility with Six3 right?
> But what if I do not need compatibility? I just want to understand. (maybe
> someone uses Six in a Clipper program and a Harbour program on the same
> database? Is this the motive?)
Exactly. Harbour can share encrypted tables with SIX3 Clipper applications
if they do not use memo fields.
We can add BlowFish encryption to Harbour DBF* RDDs but it should be wider
implementation then SIX3 one which does not touch few things like indexes
from which keys can be read by anyone.
There is only question if it's worth to touch RDD to reach such effect.
Few years ago I added to Harbour new file IO meta layer and updated all
native RDDs to use it. So far we have two drivers using this meta layer:
NETIO written by me and MEMIO written by Mindaugas. Looks that other
developers still do not see how powerful is this extension.
It's possible to write new driver, i.e. BFIO (BlowFishIO) which will crypt
and decrypt all data written to and read from files. It can be implemented
in few hours by anyone with some knowledge about C and Harbour internals.
It can even use replaceable encryption methods. Using CFB (cipher feedback)
encryption mode then we can also use any hash function as base for
encryption algorithm.
Below I'm attaching simple example which uses MD5 hash function to encode
and decode text. Please remember that CFB encryption method does not change
the size of encrypted data what can be important in some cases, i.e. fixed
field size in tables or variable length datagram encoding.
best regards,
Przemek
/*************************************************************************/
proc main()
test( "This is a top secret message only by trusted people." )
?
test( repl( "A", 63 ) )
return
proc test( text )
local cipher, result
cipher := HB_MD5ENCRYPT( text , "top-secret" )
result := HB_MD5DECRYPT( cipher, "top-secret" )
? len( text ), hb_valToExp( text )
? len( cipher ), hb_valToExp( cipher )
? len( result ), hb_valToExp( result )
? text == result, iif( text == result, "OK", "ERROR" )
return
/*************************************************************************/
#pragma begindump
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbchksum.h"
/*
* Harbour Project source code:
* PRG functions for MD5 encryption/decryption using
* CFB (cipher feedback) mode
*
* Copyright 2011 Przemyslaw Czerpak <druzus / at /
priv.onet.pl>
* www -
http://harbour-project.org
*/
static void hb_md5_init_seed( char * vect, const char * pszKey, int iLen )
{
hb_md5( pszKey, iLen, vect );
}
static void hb_md5_next_seed( char * vect, const char * pszKey, int iLen )
{
int i;
for( i = 0; i < 16; ++i )
vect[ i ] ^= pszKey[ i % iLen ];
hb_md5( vect, 16, vect );
}
/* HB_MD5ENCRYPT( <cText>, <cPasswd> ) -> <cCipher>
*/
HB_FUNC( HB_MD5ENCRYPT )
{
PHB_ITEM pData = hb_param( 1, HB_IT_STRING );
if( pData && hb_parclen( 2 ) > 0 )
{
HB_SIZE nLen = hb_itemGetCLen( pData ), n;
if( nLen )
{
const char * pszSource = hb_itemGetCPtr( pData );
char * pszData = ( char * ) hb_xgrab( nLen + 1 );
const char * pszKey = hb_parc( 2 );
int iLen = ( int ) hb_parclen( 2 );
char vect[ 16 ];
hb_md5_init_seed( vect, pszKey, iLen );
for( n = 0; n < nLen; ++n )
{
int i = ( int ) ( n & 0x0F );
if( i == 0 )
hb_md5_next_seed( vect, pszKey, iLen );
pszData[ n ] = ( vect[ i ] ^= pszSource[ n ] );
}
hb_retclen_buffer( pszData, nLen );
}
else
hb_retc_null();
}
}
/* HB_MD5DECRYPT( <cCipher>, <cPasswd> ] ) -> <cText>
*/
HB_FUNC( HB_MD5DECRYPT )
{
PHB_ITEM pData = hb_param( 1, HB_IT_STRING );
if( pData && hb_parclen( 2 ) > 0 )
{
HB_SIZE nLen = hb_itemGetCLen( pData ), n;
if( nLen )
{
const char * pszSource = hb_itemGetCPtr( pData );
char * pszData = ( char * ) hb_xgrab( nLen + 1 );
const char * pszKey = hb_parc( 2 );
int iLen = ( int ) hb_parclen( 2 );
char vect[ 16 ];
hb_md5_init_seed( vect, pszKey, iLen );
for( n = 0; n < nLen; ++n )
{
int i = ( int ) ( n & 0x0F );
if( i == 0 )
hb_md5_next_seed( vect, pszKey, iLen );
pszData[ n ] = ( vect[ i ] ^ pszSource[ n ] );
vect[ i ] = pszSource[ n ];
}
hb_retclen_buffer( pszData, nLen );
}
else
hb_retc_null();
}
}
#pragma enddump
/*************************************************************************/