The final question we address is how to prevent unauthorized writers from making authentic changes to the persistent store. Because the only parties involved in the actual write are the server and the user who wishes to write, we need a mechanism for the server to validate writes.
In traditional storage systems, this has been accomplished using some form of an access control list (ACL); the server permits writes only by those on the ACL. This requires that the ACL be stored securely, and the server authenticates writers using the ACL.
In Plutus, a file owner stores a hash of a write token stored on the server to validate a writer. This is semantically the same as a shared password.
Suppose a filename
is not encrypted. The owner of the file creates a
write-verification key
as the write token. Then,
and the hash of the write token,
, are stored on the server in
the file's inode.
Upon authentication, writers get the write token
from the owner.
When writers issue a write, they pass the token to the
server. To validate the write, the
server can now compute
and compare it with the stored
value. Readers cannot generate the appropriate token because they do not
know
. The token is secure since the hash value is stored only on the
server. Optionally the server can cache the hashed write tokens to
speed up write verification.
One problem with the above scheme is that from
, anyone can
learn useful structural information such as which files belong to
which filegroup even when the filegroup name is encrypted. This is
undesirable given that storage system itself can be stolen and it does
not do any authentication of the readers. Such attacks can be
thwarted by replacing
with
and the filegroup name
with
, where
is the filegroup-name key.
The write token used above is similar to the capabilities used in NASD [19] and many systems before [29]. However capabilities in general are given out by a centralized server whereas write tokens are generated by individual file owners and are given to writers in a distributed manner.
The benefit of this approach is that it allows an untrusted server to verify that a user has the required authorization, without revealing the identity of the writer to the server. The scheme also makes it easy for the server to manage the storage space by decoupling the information required to determine allocated space from the data itself. Though the actual data and (possibly) filenames and filegroup names are encrypted and hidden, the list of physical blocks allocated is visible to the server for allocation decisions.
There are several file systems such as Cedar [18], Elephant [41], Farsite [1], Venti [38], and Ivy [36], which treat file data as immutable objects. In a cryptographic storage file system with versioning, server-verified writes are less important for security. Readers can simply choose to ignore unauthorized writes, and servers need worry only about malicious users consuming disk space. In non-versioning systems, a malicious user could corrupt a good file, effectively deleting it.