On 29/03/2011 2:38 AM, Nebu Pookins wrote:
If you have some secure data floating around in your db, encryption can
> still be a good idea. Parts of one of my databases are encrypted, because
> users need to be able to see some documents in the db but not others.
I'm curious as how you've implemented encryption in your DB. Was it
pure JavaScript, or did you use native libraries? Elsewhere in this
thread, I've started a new "branch" where I've started outlining my
concerns with a pure JavaScript solution and wondered if cryptography
could be included as a core feature of CouchDB.
I'm using couchdb as a database, not to serve up pages directly to
users. As a consequence, a 'user' is a web application, and multiple
applications have differing levels of access to the database.
Each application is allowed to store it's own 'application data'
documents and I override two methods in my document class to allow
transparent decryption/encryption of those docs when read/written. (see
below)
The reason I implemented encryption is that there's no per-doc read
access control in couchdb, so without encryption, I'm not able to
prevent applications from accessing another application's document. It's
not as good a solution as proper access control.
-Patrick
/**
* Given an object - load all the attributes from it into the document
- displacing existing attributes.
* If the data field is encrypted, attempts to decrypt it.
* @param stdClass $obj : An object with the desired attributes.
**/
public function loadFromObject(stdClass $obj) {
parent::loadFromObject($obj);
if ($this->doc_type != 'appdata') throw new
InvalidArgumentException("Wrong object type - Cgm_Appdata is for appdata
only");
//Does the data section need to be decrypted?
if (isset($this->encrypted) and $this->encrypted == true) {
// Check that decryption info is stored
$conf = Cgm_Document_Gateway::getAppConfig($this->source);
if (!$conf->decrypt) throw new LogicException("Cannot load
document - no decryption is configured, and the document is encrypted.");
// Decrypt and decode the data
$decryptor = new Zend_Filter_Decrypt($conf->decrypt);
$raw = base64_decode($this->data);
$plain_json = trim($decryptor->filter($raw));
$plain = json_decode($plain_json);
if ($plain === NULL) throw new LogicException("Cannot load
document - decryption configuration is incorrect.");
// Store the plain data within the object, in the same way
as a non-encrypted object.
$this->data = $plain;
unset($this->encrypted);
}
}
/**
* Export to an object.
* If encryption is configured, attempts to encrypt the data field.
* @return stdClass $obj
*/
public function exportToObject() {
$obj = parent::exportToObject();
//Should the data section be encrypted?
$conf = Cgm_Document_Gateway::getAppConfig($this->source);
if ($conf->encrypt) {
$encryptor = new Zend_Filter_Encrypt($conf->encrypt);
$cryptdata = base64_encode( $encryptor->filter(
Zend_Json::encode($obj->data) ) );
$obj->data = $cryptdata;
$obj->encrypted = true;
}
//Was it encrypted before? - ensure that the flag is cleared
elseif (isset($obj->encrypted)) {
$obj->encrypted = false;
}
return $obj;
}