How to work with Blowfish encryption
Posted: Mon Jan 06, 2014 9:11 pm
After some testing, it seems the only special "tricks" needed for working with Blowfish are that A) all fields must be of char data type; B) all fixed-length fields to be encrypted in a DBF must be 8 bytes long or some multiple of 8 bytes in length (16, 24, 32, etc.), and C ) the last byte of each field must be reserved for Blowfish's checksum code. So the actual data, besides being of character type, must be restricted to either 7, 15, 23, 31 etc. bytes in length. If space is not reserved for the checksum, then Blowfish will automatically add another 8 bytes to the data, which will get truncated when stored in the DBF, thereby losing the checksum - without which the data cannot be decrypted. Because memos are of variable length, the checksum byte won't get cut off, so no special data length is required for memos.
Before either encrypting or decrypting with Blowfish, you first have to get a key for each field with code like this: cBfkey := hb_blowfishkey("FiveWin=Mother'sMilk"). Of course, each field can have a different key for heightened security.
Thus to encrypt data in an 8 char field, the code is: MyField := hb_blowfishencrypt( cBfkey, SUBSTR(MyField,1,7) ) where MyField must be a char field. If encrypting a memvar, use SUBSTR(MyMemvar,1,7) in the code to provide the proper 7 char data limit for data going into an 8 char field. For larger fields/memvars (that will be saved to fields), all with lengths that are some multiple of 8, then instead of a limit of 7, use a limit number that is 1 less than the field/memvar length to allow space for the checksum.
To decrypt a field, no special length coding is needed. So the code is: MyField := hb_blowfishdecrypt( cBfkey, MyField). In the decryption, Blowfish will automatically drop the checksum byte leaving just your clear data.
If you need to work with logical (.t. or .f.) data, then it will have to be converted to char data, but stored in an 8 byte field. Encrypt as if you have 7 bytes of data (6 bytes are blanks) reserving the 8th byte for the checksum. When retrieved and decrypted, convert back to logical data type for processing. Likewise, numeric data - to be encrypted - must first be converted to char and then stored in a field that is 8 char long or some multiple thereof. Again, use SUBSTR(MyData,1,7) - or whatever appropriate length as noted above - as part of the encryption coding.
Before either encrypting or decrypting with Blowfish, you first have to get a key for each field with code like this: cBfkey := hb_blowfishkey("FiveWin=Mother'sMilk"). Of course, each field can have a different key for heightened security.
Thus to encrypt data in an 8 char field, the code is: MyField := hb_blowfishencrypt( cBfkey, SUBSTR(MyField,1,7) ) where MyField must be a char field. If encrypting a memvar, use SUBSTR(MyMemvar,1,7) in the code to provide the proper 7 char data limit for data going into an 8 char field. For larger fields/memvars (that will be saved to fields), all with lengths that are some multiple of 8, then instead of a limit of 7, use a limit number that is 1 less than the field/memvar length to allow space for the checksum.
To decrypt a field, no special length coding is needed. So the code is: MyField := hb_blowfishdecrypt( cBfkey, MyField). In the decryption, Blowfish will automatically drop the checksum byte leaving just your clear data.
If you need to work with logical (.t. or .f.) data, then it will have to be converted to char data, but stored in an 8 byte field. Encrypt as if you have 7 bytes of data (6 bytes are blanks) reserving the 8th byte for the checksum. When retrieved and decrypted, convert back to logical data type for processing. Likewise, numeric data - to be encrypted - must first be converted to char and then stored in a field that is 8 char long or some multiple thereof. Again, use SUBSTR(MyData,1,7) - or whatever appropriate length as noted above - as part of the encryption coding.