Using JDataStore's Security Features

JDataStore is a feature of JBuilder Professional and Enterprise, and the Inprise Application Server.

JDataStore provides several built-in security features. This collection of features provides user authentication, user authorization, and encryption for JDataStore databases.

User authentication

By default JDataStore databases do not require users to be authenticated to access the database. JDataStore authentication support can be enabled by adding at least one user to the SYS/USERS system table in a JDataStore database. This can be done either programmatically, or by using JDataStore Explorer.

The SYS/USERS table is read-only if it is accessed by a JDBC query or a StorageDataSet.

When users are added, their initial password and database rights are supplied.

There are three methods that can be used to administer users. DataStoreRights.ADMINISTRATOR rights are required to call these methods.

DSX: See "Administering Users" for an explanation of administering users using the JDataStore Explorer.

There is a DataStoreConnection.changePassword() method that can be used to change a password. Any user can change their own password. It requires knowledge of the existing password, but does not require DataStoreRights.ADMINISTRATOR rights.

DSX: For instructions on changing a password through the JDataStore Explorer, see "Changing a password".

Authorization

Database rights are supported by specifying the constants in the com.borland.datastore.DataStoreRights interface. The rights specified by DataStoreRights include:

JDataStore Encryption

A DataStoreRights.ADMINISTRATOR user can encrypt an empty database that has a DataStoreConnection.getVersion() of DataStore.VERSION_6_0 or greater. The DataStoreConnection.encrypt() method can be used to encrypt databases.

DataStoreConnection.encrypt() will remove DataStoreRights.STARTUP from all users except for the administrator that is adding the encryption. This is because the user's password is required to add STARTUP rights to a user. To provide STARTUP rights to a user, call DataStoreConnection.changeRights(), or drop the user and then add the user back.

Note: A database with existing table or file streams will not be encrypted. If you want to encrypt an existing database, create a new database, call DataStoreConnection.copyUsers() to copy the existing users to the new database, then go ahead and encrypt the new database. Then call DataStoreConnection.copyStreams() to copy the contents of the old database into the encrypted database. For more information on copying streams see "Copying JDataStore Streams".

DSX: See "Encrypting a JDataStore" for information on how to encrypt a JDataStore using the JDataStore Explorer.

Deciding how to apply JDataStore security

In this discussion an opponent is someone who is trying to break the JDataStore security system.

The authentication and authorization support is secure for server side applications where opponents do not have access to the physical JDataStore files. The SYS/USERS table stores passwords, user IDs, and rights in encrypted form. The table also stores the user ID and rights in an unencrypted column, but this is for display purposes only. The encrypted values for user ID and rights are used for security enforcement.

The stored passwords are encrypted using a strong TwoFish block cypher. A pseudo-random number generator is used to salt the encryption of the password. This makes traditional password dictionary attacks much more difficult. In a dictionary attack, the opponent makes guesses until the password is guessed. This process is easier if the the opponent has personal information about the user, and the user has chosen an obvious password. There is no substitution for a well chosen (obscure) password as a defense against password dictionary attacks. When an incorrect password is entered, the current thread sleeps for 500 milliseconds.

If a JDataStore database is unencrypted, it is important to restrict physical access to the file, for the following reasons:

For environments where a dangerous opponent may gain access to physical copies of a JDataStore, the database and log files should be encrypted, in addition to being password protected.

Warning: The cryptographic techniques that JDataStore uses to encrypt data blocks is state of the art. The TwoFish block cypher used by JDataStore has never been defeated. So this means that if you forget your password for an encrypted JDataStore database, you are really out of luck. The best chance of recovering the data would be to have someone guess the password.

There are measures that can be used to guard against forgetting a password for an encrypted database. It is important to note that there is a master password used internally to encrypt data blocks. Any user that has STARTUP rights will have the master password encrypted using their password in the SYS/USERS table. This allows one or more users to open a database that has been shutdown because their password can be used to decrypt a copy of the master password. This feature can be used to create a virgin database that has one secret user in it that has DataStoreRights.ADMINISTRATOR rights (which includes DataStorerights.STARTUP rights). If this virgin database is used whenever a new empty database is needed, you will always have one secret user that can unlock the encryption.

Encrypting a database will affect performance somewhat. Data blocks are encrypted when they are written from the JDataStore cache to the JDataStore database file. Data blocks are decrypted when they are read from the JDataStore database file into the JDataStore cache. So the cost of encryption is only incurred when file I/O is performed.

JDataStore encrypts all but the first 16 bytes of .jds file data blocks. There is no user data in the first 16 bytes of a data block. Some blocks are not encrypted. This includes allocation bitmap blocks, the header block, log anchor blocks and the SYS/USERS table blocks. Note that the sensitive fields in the SYS/USERS table are encrypted using the user's password. Log file blocks are completely encrypted. Log anchor and status log files are not encrypted. The temporary database used by the query engine is encrypted. Sort files used by large merge sorts are not encrypted, but they are deleted after the sort completes.

Note that the remote JDBC driver for JDataStore currently uses Java socket classes to communicate with a JDataStore Server. This communication is not secure. Since the local JDBC driver for JDataStore is in-process, it is secure.