Page
Library
Module
Module type
Parameter
Class
Class type
Source
Cryptodbm
SourceThis library provides an encrypted layer on top of the Dbm and Cryptokit packages. The improvements over Dbm are:
As a quick example, the following uncrypted bindings (key => data):
"john-doe" => "age 36" "some secret" => "The cake is a lie." "Motto" => "For relaxing times, make it Suntory time"
are stored as follows in the encrypted file (with variations depending on the password, and other parameters):
[S~j....O.Q..tk^.2] => [...F...).Hsl..tB] [...y;....~.:.6V.2] => [....I...JR..w.E9..G..q=...K....b] [..'.C...F.x.3K.y2] => [1.)9q..M...et.b.] [S.....5 Y....8..2] => [.D........2..u...q.......}Z.b..z.zo.}.l3l.....>.] [...xD;@.8..wV..P1....e}....u..`.2] => [hb..2.._B....Y?0....|.....tM....] [K.#i.7j..H.ZZ.^.2] => [..z....,........]
Including several subtables in the same database file avoids having to deal with multiple files to store related information, and also prevents information leak through the number and sizes of a set of database files.
This library was primarily designed to store encrypted exam files on a university server. A common layout consists in several subtables encrypted with a global password, as well as an uncrypted subtable containing (public) meta-information.
Install and compile
Install using opam: opam install cryptodbm
Compile with ocamlbuild by adding the following to your _tags file:
<**/*> : package(cryptodbm)
Performance
I have not benchmarked this library. Keep in mind that every access (reading or writing a binding) requires to encrypt the key, and encrypt the data (when writing) or decrypt the data (when reading). Don't be pessimistic, though: it seems all right for non critical applications.
Also, there is only a global key-index for the whole table, no key-index for individual subtables. As a consequence, subtable iterators actually iterate over the whole table index (selecting only the expected subtable indexes).
A few technical details
When a database file is encrypted,
See also the project homepage.
Contact: D. Le Botlan (github.lebotlan@dfgh.met where you replace .met by .net.)
let table = open_append ~file:"/path/to/myfile" ~passwd:"my-secret-passwd" in
let subtable = append_subtable table ~name:"here the subtable name" () in
add subtable ~key:"key1" ~data:"data1" () ;
add subtable ~key:"key2" ~data:"data2" () ;
close table ;
()
Notice that all functions may raise Error(DB_Error)
when accessing the underlying database.
The type of encrypted-dbm file descriptors. 'a is a phantom type precising the permission: read-only or full access.
Phantom type which represents read-only permission.
Phantom type which represents read-write permission.
Type of a subtable. 'a is the permission.
The database can be opened in three modes: read mode, write (create) mode, and append mode.
Note that operations are not thread-safe at the library level: do not share a table or subtable handler between threads. However, multiple processes might access the same database, whenever the low-level dbm permits it (which depends on the low-level dbm library actually used). gdbm allows many readers in parallel, or only one writer and no reader.
val open_read :
?iterations:int ->
file:string ->
passwd:string ->
signwd:string ->
unit ->
read table
Opens an encrypted-dbm file for reading.
val open_append :
?iterations:int ->
file:string ->
passwd:string ->
signwd:string ->
check_signature:bool ->
unit ->
full table
Opens an existing encrypted-dbm file in append mode.
val open_create :
file:string ->
?overwrite:bool ->
?iterations:int ->
passwd:string ->
signwd:string ->
?max_extra_key:int ->
?max_extra_data:int ->
?max_extra_bindings:int ->
perm:int ->
unit ->
full table
Creates a new encrypted-dbm file.
val open_only_uncrypted :
?iterations:int ->
file:string ->
signwd:string ->
unit ->
read table
Opens a table to access only uncrypted subtables.
If in write mode, sign if necessary, add extra bindings if required, then flush and close the file. In read mode, just close the file. All the subtables are automatically closed.
Sign if necessary, and flush. Optionally make a backup, that is, a copy of the current database file is made (default name is: 'filename'-backup-'date').
Returns the root filename (without the .pag or .dir extension).
val create_subtable :
full table ->
name:string ->
?iterations:int ->
passwd:string ->
signwd:string ->
?max_extra_key:int ->
?max_extra_data:int ->
unit ->
full subtable
Creates a standard subtable for writing.
val create_uncrypted_subtable :
?iterations:int ->
full table ->
name:string ->
signwd:string ->
unit ->
full subtable
Creates an uncrypted subtable (even when the global table is encrypted).
val open_subtable :
'a table ->
name:string ->
?iterations:int ->
passwd:string ->
signwd:string ->
unit ->
read subtable
Open a standard subtable for reading.
val open_uncrypted_subtable :
?iterations:int ->
'a table ->
name:string ->
signwd:string ->
unit ->
read subtable
Open an uncrypted subtable for reading.
val append_subtable :
full table ->
name:string ->
?iterations:int ->
passwd:string ->
signwd:string ->
check_signature:bool ->
unit ->
full subtable
Open a standard subtable for appending bindings.
val append_uncrypted_subtable :
?iterations:int ->
full table ->
name:string ->
signwd:string ->
check_signature:bool ->
unit ->
full subtable
Open an uncrypted subtable for appending bindings.
If in write mode, sign if necessary, then flush and close the subtable. In read mode, just close the subtable.
Iterate over standard subtables. The function is applied to the subtable name and number.
Iterate over uncrypted subtables.
add subt key data
binds key
to data
in subtable subt
. By default, overwriting an existing binding is forbidden.
find subt key
returns the data associated to key
in subtable subt
.
delete subt key
removes the binding associated to key
in subtable subt
.
Iterate over all pairs (key, data) of the given subtable.
Iterate over all keys of the given subtable. Faster than iter
since data is not decrypted.
The underlying database file is managed by the dbm library actually installed on the runtime platform. For portability, or to ensure that your data does not depend on a particular version of the dbm library, you can use these functions which convert dbm files to and from an ad-hoc, very simple binary format.
Exports a dbfile to a durable binary format. The dbfile must be opened for reading (open_only_uncrypted suffices, in case the passwords are not known). Note that the binary file just mirrors the dbfile (that is, they both contain the same encrypted & uncrypted data).
Imports a binary file to a dbfile. dbfile
is the output dbfile, without .pag or .dir extension