DataBase was a system created to demonstrate how to encrypt
database records on disk. The design shows how the use of object inheritance
makes the intrigration of the encryption virtualy seemless.
Fetches:
- Use of any block cipher
- Cipher Block Chaining (CBC) for stored data
- Compleat random access
How it works
This is a Pascal demonstration, so I assume some knowledge
of Pascal with objects. C++ dudes should be able to follow-- but I'm
not going to speak in C++ terms when I wrote the demo in Pascal.
Details of the guts:
What acualy goes on durring saving and retrivial is simply
the use of the blockcipher in Cipher Block Chaining (CBC) mode.
The file location is used as the Initilizing Vector (IV) and each record
is written as a stream in this fassion. In this way, all data is
encrypted in a streaming fassion and is still accessable in random order.
This provides strength over using ECB (Electronic Code Book) mode on the
records, (which would also alow random record access) which is vurnibal
to known-plain text atacks.
Asside from the CBC methods just discused, the object does
nothing more than compute the size of itself for reading and writting
purposes. This makes for a simple and clean interface, and when
used with good sucirity house keeping pratices, makes for a sucure database
encryption system.
Intended use of the example
First, basics:
To create an encypted database record, define the elements
of the database record as would be done with a standard 'record'.
{ Example }
type
PersonRecord = record
{
Name }
FirstName
: string[ 15
];
LastName
: string[ 15
];
{ Address (setup
for US addresses) }
StreetAddress
: string[ 40
];
City
: string[ 40
]
State
: string[ 2
];
ZipCode
: string[ 5
];
{ Phone number
with dashes (US phone number) }
PhoneNumber
: string[ 12
];
end;
Above, we have a basic database for storing personal contact
information. For a gerneric card file database, records such as
this could be stored on disk on after an other. Being all the same
size, they can be accesseed in random order if the index location in the
array is known. External files containing indexes can be used if
sorting (ie. sorting alphabeticly).
Storing database encrypted:
The unit 'RecordEncrypt' has the base object 'EncryptedObject'.
For the example above, include the 'RecordEncrypt' unit and change
the record into an object inheriting 'EncryptedObject'.
{ Example }
uses
RecordEncrypt;
...
type
PersonRecord = object(
EncryptedObject )
...
end;
An instance of 'PersonalRecord' is all that is needed
to save and retrive information from the encrypted file.
Before starting the data side of things, the cipher must
be setup. That is, a blockcipher must be selected and a key specified
for encryption. This is a standard 'Cipher' object as used
in the normal Cypher project. Once an instance of the blockcipher
is setup, the instance of the encrypted object is initilize with the cipher.
{ Example }
var
Person
: PersonRecord;
Cipher
: PCipherClass;
Key
: ^ByteArray;
begin
{ Use the Advance Encryption
Standard (AES) algorithm }
Cipher := CipherList^.Find(
'AES' );
...
{ Initilize cipher
with key }
{ Assume 'Key' has
a keystring in it }
Cipher^.PrepareKey(
Key^ , Cipher^.KeySize );
...
{ Initlize the cipher
being used }
Person.Init( Cipher
);
...
end.
Now the cipher is initilized and acosseated with the 'Person'.
We can now read and write data to and from a file. (For more information
on the correct way to initilize the blockcipher along with key generation
pratices, look more at the Cypher project.)
{ Example }
var
Person
: PersonRecord;
DataFile
: file;
begin
{ Assume 'Person' has
been initilized with cipher }
...
{ Open file for data
}
Assign( DataFile ,
'Personal.Dat'
);
Reset( DataFile , 1
);
...
{ First record }
Person.FirstName :=
'Punkroy';
Person.LastName
:= 'Punker';
{ Save record to file
}
Person.WriteBlock(
DataFile );
{ Second record }
Person.FirstName :=
'John';
Person.LastName
:= 'Smith';
{ Save record to file
}
Person.WriteBlock(
DataFile );
{ Close database file
}
Close( DataFile );
end.
Above, two records are "stuffed" and saved one after an
other.in 'Personal.Dat'. If 'Personal.Dat' is viewed
in a hexediter, the content will be encrypted.
Now, when accessing records in the file, simply seek to the
location in the file the record entry is located and use the member function
'ReadBlock' to read the record data into the instance.
var
Person
: PersonRecord;
DataFile
: file;
begin
{ Assume 'DataFile'
is assigned and open }
...
{ Goto first record
}
Seek( DataFile , 0
);
{ Read record }
Person.ReadBlock( DataFile
);
...
end.
This example retrives the first record of an encrypted file.
The record data is in 'Person'. It can then viewed and changed.
After changes have been made, the record must again be stored. Remember:
Be sure and seek to the location in the file the data is to be stored--
'WriteBlock' writes data to warever the file position is located.
|