Switch to: V10V9V8V7V6V5

Valentina Encryption

Valentina has the ability to encrypt fields, tables or the entire database. This allows you to protect your information from analysis using file utilities such as HexEdit.

The encryption Key is not stored in the database.

ATTENTION: If you forget your encryption key, there is no way to decrypt the data.

Variants of encryption

Valentina has very flexible and strong encryption abilities. You can:

  1. Encrypt only the structure (schema) of the database.
    This prevents the ability to open and view your database with any other application which understands the Valentina format.
  2. Encrypt data of the entire database.
    This option provides the highest level of protection, since all database data is encrypted (except structure).
  3. Encrypt data of one or more tables.
    This option allows you to encrypt table(s) with confidential information and still have excellent performance for other tables.
  4. Encrypt data of one or more fields.
    This option allows you to encrypt field(s) with confidential information and still have excellent performance for other tables/fields.

Algorithm of encryption

By default Valentina uses the Blowfish encryption algorithm. BlowFish is both a strong (448 bits) and fast algorithm. Its Encryption Key is a string that can be from 1 to 72 characters long, with a longer key providing stronger security.

Hierarchy of encrypted objects

Valentina implements a hierarchy for the inheritance of encryption parameters.

  VDatabase -> VTable -> VField

This means that if you encrypt the Database object, all child objects are encrypted with the same key as well. If you create a new Table in the encrypted database, this Table also is encrypted with the same key. The same is true for fields.

Note: You can not encrypt an object with its own key if the parent object is already encrypted. This is prohibited in order to avoid a conflict of keys. If you try to do this, Valentina will return the error: “This object already is encrypted”.

Note: The Database and Table just play the role of a keeper of the key and pass it to the child objects. Table Fields perform the real encryption work. When Valentina encrypts a field then its index is encrypted too if it exists. Binary links are never encrypted because they do not contain user information.

API of encryption

The VDatabase, VTable and VField Classes have a similar set of methods to work with encryption.

The first group of methods allows you to encrypt or decrypt an object and to change the encryption key.

void Encrypt( EncryptionKey_Ptr inKey );
void Decrypt( EncryptionKey_Ptr inKey );
void ChangeEncryptionKey( EncryptionKey_Ptr inOldKey, EncryptionKey_Ptr inNewKey );

EncryptionKey is a helper class:

class EncryptionKey ...
    const vuint8* 	inKeyString, 
    vuint32 		inKeyLen );

Similar methods to encrypt/decrypt structure (schema):

void EncryptStructure( EncryptionKey_Ptr inKey );
void DecryptStructure( EncryptionKey_Ptr inKey );
void ChangeStructureEncryptionKey( EncryptionKey_Ptr inOldKey, EncryptionKey_Ptr inNewKey );

The second group of methods allows you to access an already encrypted object.

void UseEncryptionKey( EncryptionKey_Ptr inKey );
void UseStructureEncryptionKey( EncryptionKey_Ptr inKey );

Before you get access to an object you usually need to check wether the object is encrypted. To do this, each of the three classes has two properties:

bool get_IsEncrypted(void);
bool RequiresEncryptionKey(void);

The VDatabase class has an additional property:

bool get_IsStructureEncrypted(void);

It is important to understand the difference between the properties IsEncrypted and RequiresEncryptionKey.

IsEncrypted - returns TRUE for an object that is encrypted by its own key, or for an object which inherited a key from the parent object.

RequiresEncryptionKey - returns TRUE only if the object is encrypted by its own key. This allows the application to ask for a key from the user when accessing an encrypted object. The application will not ask for a key for each of its child objects, since it knows that access to these objects already has been granted. Note that each such child object will return FALSE for RequiresEncryptionKey.

Usually the RequiresEncryptionKey property is used during the development of an application to check whether a key is required for a Table or a Field. For a Database object this property is not so much important because a database does not have a parent object.

Usage of Database encryption

Encryption of Database data

Most often you will encrypt the whole database. To do so, you can use the method VDatabase.Encrypt().

You can perform this operation on an empty database as well as on a database with records. This operation should be executed on an open database.

Note: The time required for this operation is directly proportional to the size of the database.

void EncryptDatabase( VDatabase inDB )
    inDB.Create(); // db is in open state after create
    inDB.Encrypt( new EncryptionKey("password",8) );
void EncryptDatabase( VDatabase inDB )
    inDB.Encrypt( new EncryptionKey("password",8) );

Decryption of Database data

If you want to decrypt database data, you can use the method VDatabase.Decrypt().

You can perform this on an empty database as well as on a database with records. This operation should be executed on an open database.

Note: The time required for this operation is directly proportional to the size of the database.

void DecryptDatabase( VDatabase inDB )
    inDB.Decrypt( new EncryptionKey("password",8) );

Changing the encryption key

To change the encryption key you should use the method Vdatabase.ChangeEncryptionKey().

You can perform this operation on an empty database as well as on a database with records. This operation should be executed on an open database.

Note: The time this operation requires is directly proportional to the size of the database.

inDB.ChangeEncryptionKey( new EncryptionKey("password",8), new EncryptionKey("NewPassword",11) );

Accessing an encrypted database

To access an encrypted database you should use the method UseEncryptionKey(). We have two possible cases:

  • the application knows exactly that the database is encrypted
  • the application can open an encrypted database or a non-encrypted database

The latter case happens mainly for DBMS type applications like Valentina Studio.

In the first case, the code can look like the following:

OpenEncrypted( db )
    db.UseEncryptionKey( new EncryptionKey("password",8) ) // never produces error
    catch( xEception exc )

In the second case it is necessary to do additional checks and choose one of the following execution branches:

OpenUnknown( db )
    db = new VDatabase();
        db.Open();  -- can throw error ERR_ENCRYPTION_NOT_ENCRYPTED 
    catch( xEception exc )
    // Ask user for a password. E.g. VStudio may need this.
    passw = ...;
    // then open db using that password:
    OpenEncrypted( passw );

Some peculiarity of encrypted database

In case of encrypted database you should define proper encryption keys before open() call. If keys are not valid you will get an exception opening the database. You should not use IsEncrypted or RequiresEncryptionKey properties on closed database. So the only chance to check - is a database encrypted or not - is attempt to open it providing no keys ( ERR_ENCRYPTION_WRONG_ENCRYPTION_KEY error means database is encrypted).

Usage of Table encryption

The work involved with Table encryption is in general simpler than with database encryption since there exist fewer operations.

Operations that make sense for Table encryption are very similar to operations for database encryption: Encrypt(), Decrypt(), ChangeEncryptionKey().

Note: you can encrypt a Table only if its database (parent object) is not encrypted. Otherwise you will receive the error message “Object already is encrypted”.

Getting access to an encrypted Table

If you develop a DBMS type of application, you will need to check wether a Table requires its own encryption key for access.

void ShowTable( VTable tbl )
    if( tbl.RequiresEncryptionKey() == true ) 
        String passw = AskUserPasswordFor( tbl );
        tbl.UseEncryptionKey( new EncryptionKey( passw.get_BufferA(), passw.length()) ); // can throw.
    // do work to show records of Table.

Usage of Field encryption

The commands for field encryption are absolutely the same as with Table encryption. See above description of Table encryption.