Specification of Encryption for Valentina 2.0

Lynn Fredricks lfredricks at proactive-intl.com
Sun Jul 31 09:52:01 CDT 2005


Hi Ruslan,
 
I have a question: Can you think of a possibility in which someone would
need to be granted limited access to part of a database, such as a single
table in a database, or a few fields? In such a case, how would this be
handled?
 
Also, we do need some level of error handling if someone doesnt have a
password -- because it certainly happens in real life ;-) Shouldnt there be
a default method and then (in the more powerful C++ SDK) a way for this to
be modified or replaced by custom code? I can see how it may be desirable,
for example, to pass back nothing (but the attempt is logged someplace).
Best regards,

Lynn Fredricks
President
Proactive International, LLC

- Because it is about who you know.(tm)
http://www.proactive-intl.com <http://www.proactive-intl.com/> 
-Software Destinations
http://www.proactive-intl.com/blogs/ 


  _____  

From: valentina-beta-bounces at lists.macserve.net
[mailto:valentina-beta-bounces at lists.macserve.net] On Behalf Of Ruslan
Zasukhin
Sent: Sunday, July 31, 2005 8:56 AM
To: valentina at lists.macserve.net; valentina-beta at lists.macserve.net; Igor
Gomon; Jochen Peters
Subject: Specification of Encryption for Valentina 2.0


/***************************************************************************
***/
Specification (point of user)

* User can encrypt
    - the whole database.
    - one or few tables.
    - one or few fields.

* User cannot encrypt links. 
    Valentina 2.0 have Binary Links. But since they keep only values of
RecIDs
    there is no sense to encrypt them.                
                  
* Hierarchy of objects 
        VDatabase -> VTable -> VField

    inherit settings of encryption parameters. In other words, if user 
    have encrypt database, then each its table also is encrypted using the 
    same password. And each field of a table also is encrypted by that
password.

* User cannot assign password to an object if its supervisor already is
encrypted.
    We do not want do this to avoid ambigiouty with passwords.
    
    In case user try to assign password to a such object, then user get
ERROR
            "This object already is encrypted"        
        
* Note that the main job do VField. VDatabase and VTable objects play just a
role of 
    password-keeper. So VField encrypt data stored in column of Table, also
    indexes of the field is encrypted.

* If user forget password then big problems. Because nobody can decrypt that
database.

* Each of classes VDatabase, VTable and VField implements interface
I_Encryptable.    

* Important to note that you should never try read data that are encrypted
until
    you specify correct password. So first of all you must check that you do
not
    get error WRONG_PASSWORD, and only after this try to read data.   

* What happens if user try read data without password? Hard to say...
    He can see garbage, or may be NULLs or may be empty strings.
    In ideal system must not crash on access to such non-encrypted data,
    although it seems it is hard to implement this. 


/***************************************************************************
***/
* Interface I_Encryptable offer to user the next operations:

// Properties:

    // -----------------------------------------------------------------
    IsEncrypted : bool        

        DESCRIPTION: Returns TRUE if this object is encrypted,
            never mind how -- directly or by supervisor. 


    // -----------------------------------------------------------------
    RequirePassword : bool        

        DESCRIPTION: Returns TRUE if this object is root of encryption,
            and user must specify password to get access to data of this
object
            and all its sub-objects.


// Group of methods to encrypt/decrypt:

    // -----------------------------------------------------------------
    Encrypt( inPassword: string ) : void

        DESCRIPTION: Encrypt object using the specified password.

        ERRORS:     - "Object already is encrypted."
                    - "Object already is encrypted by supervisor."

        First error happens if user try encrypt 
        already encrypted db for example.

        Second error when user try encrypt e.g. 
        Table but its daatabse already is encrypted.


    // -----------------------------------------------------------------
    Decrypt( inPassword: string ) : void
    
        DESCRIPTION: Removes encryption for an object.

        ERRORS:     - "Object is not encrypted."
                    - "Object is encrypted by supervisor."
                    

    // -----------------------------------------------------------------
    ChangePassword( inOldPassword : string, inNewPassword : string ) : void

    
        DESCRIPTION: Changes password of encryption for an object.

        ERRORS:     - "Object is not encrypted."
                    - "Object is encrypted by supervisor."
                    - "Wrong password."    

                    
// Group of methods to get access to encrypted objects

    // -----------------------------------------------------------------
    UsePassword( inPassword : string ) : void
                    
        DESCRIPTION: Informs object by the password that it must use to
decrypt
            data when read them from database files.
            
            In case user specifies a wrong password the error will be thrown
with 
            the delay in one second to prevent hacking.

        ERRORS:     - "Object is not encrypted."
                    - "Wrong password."
            
        Errors are returned only if you apply this to Table or Field,
        i.e. database already is opened. When you apply this to a closed
database    
        then error cannot be checked, so error can be faired on db.Open().



/***************************************************************************
***/
Technical notes of implementation.

* On default we use BlowFish algorithm. This algorithm require that data are
aligned to 8 bytes.

    Taking into account that Cache pages are 4Kb, we will use this amount of
data
    as atomic set to encrypt/decrypt.

* On disk all files of encrypted objects are ALWAYS encrypted.

* We decrypt page when it is loaded into the Cache. 
    Decryption must happens before ByteSwap algorithms start work:
    Cache.Read() -> Decrypt() -> ByteSwap()      
    
* When page must go to disk we again encrypt it.
    To encrypt page, we need to use helper buffer of the same size,
    because it is no good encrypt it directly in cache, we still can use it.
    Only optimisation possible if we exactly know that this page is removed
from
    cache right now.

* interface I_Encryptable is visiable only on C++ level. 
    All rest plugins do not have it, just classes VDatabase, VTable, VField
    have set of Encryption Methods. 

        

/***************************************************************************
***/
Examples of usage:

1.1 Encryption of database (empty of with records):

    db = new VDatabase()
    db.Open()

    db.Encrypt( "password" )
    db.Close()


1.2 Opening of encrypted database:
    
  1.2.1 We know that databse is encrypted
    
    OpenEncrypted( db )
    {
        db.UsePassword( "password" )    -- never produce error
        try    
            db.Open()                    -- can throw error
NOT_ENCRYPTED, WRONG_PASSW
        catch err
    }

  1.2.2 We do not know if this databse is encrypted. 

    OpenUnknown( db )
    {
        db = new VDatabase()
        try    
            db.Open()                    -- can throw error WRONG_PASSW     
        catch err
            OpenAsEncrypted()
        end
    }


    OpenAsEncrypted()
    {
        // Ask user for a password. E.g. VStudio may need this.
        passw = ...
        
        // then open db using that password:
        OpenEncrypted( passw );
    }


1.3 Decryption of existed encrypted database

    db.Decrypt( "passw" )


1.4. Change of password:

    db.ChangePassword( "passw", "passw2" )



// ----------------------------------------------------
2.1 Database is not encrypted and we want encrypt one table

    db.Open()     -- open without password.

    db.Table( "tblEncrypted" ).Encrypt( "passwtbl" ) -- can throw error.


2.2 Database is not encrypted but one of tables is.

    db.Open()     -- open without password.

    db.Table( "tblEncrypted" ).UsePassword( "passwtbl" ) -- can throw error.


2.3 Remove encryption from single table:

    db.Table( "tblEncrypted" ).Decrypt( "passwtbl" )

-- 
Best regards,

Ruslan Zasukhin
VP Engineering and New Technology
Paradigma Software, Inc

Valentina - Joining Worlds of Information 
http://www.paradigmasoft.com

[I feel the need: the need for speed]




More information about the Valentina mailing list