Pensé un poco en las respuestas que se han publicado hasta ahora, y hay una promesa interesante en la idea de usar un algoritmo de clave pública. Pensando en voz alta, cada usuario podría tener un par de claves pública / privada (donde cada clave pública se almacena en el servidor central junto con las bases de datos).
Almacenamiento de claves públicas en el servidor:
+-------+------------------------+
| Alice | [public key for Alice] |
+-------+------------------------+
| Bob | [public key for Bob] |
+-------+------------------------+
| Carl | [public key for Carl] |
+-------+------------------------+
Cada entrada se almacenaría encriptada, utilizando un cifrado simétrico con una clave por entrada que el servidor genera aleatoriamente cada vez que se escribe una entrada:
+---+-------------------------------------------------+
| 0 | symmetric_cipher([plaintext 0], [random key 0]) |
+---+-------------------------------------------------+
| 1 | symmetric_cipher([plaintext 1], [random key 1]) |
+---+-------------------------------------------------+
| ... |
+---+-------------------------------------------------+
| 9 | symmetric_cipher([plaintext 9], [random key 9]) |
+---+-------------------------------------------------+
Para el control de acceso, una tercera asignación podría almacenar la clave generada aleatoriamente para cada entrada, que se ha cifrado utilizando la clave pública de cada usuario autorizado:
+-------+---+-------------------------------------------------------+
| Alice | 0 | pubkey_cipher([random key 0], [public key for Alice]) |
+-------+---+-------------------------------------------------------+
| Bob | 0 | pubkey_cipher([random key 0], [public key for Bob]) |
+-------+---+-------------------------------------------------------+
| Alice | 1 | pubkey_cipher([random key 1], [public key for Alice]) |
+-------+---+-------------------------------------------------------+
| Bob | 1 | pubkey_cipher([random key 1], [public key for Bob]) |
+-------+---+-------------------------------------------------------+
| ... |
+-------+---+-------------------------------------------------------+
| Alice | 8 | pubkey_cipher([random key 8], [public key for Alice]) |
+-------+---+-------------------------------------------------------+
| Carl | 8 | pubkey_cipher([random key 8], [public key for Carl]) |
+-------+---+-------------------------------------------------------+
| Alice | 9 | pubkey_cipher([random key 9], [public key for Alice]) |
+-------+---+-------------------------------------------------------+
| Carl | 9 | pubkey_cipher([random key 9], [public key for Carl]) |
+-------+---+-------------------------------------------------------+
(De lo que he leído, esto es algo de lo que hace GPG cuando envías un mensaje cifrado a múltiples destinatarios).
Cada usuario puede usar su clave privada para descifrar la clave de "entrada" simétrica que solo es válida para esa entrada específica. Esa clave les permitirá descifrar y leer esa entrada. Si necesitan cambiarlo y volver a guardarlo, pueden usar la misma clave que leen y sobrescribir, o el servidor podría generar una nueva clave de entrada y usar la clave pública para que cada usuario autorizado actualice la otra. filas.
La desautorización de un usuario sería tan simple como eliminar su fila de la tabla de asignación de usuario a entrada. Si existe la preocupación de que pueden haber almacenado una o más de las claves de entrada, todas pueden regenerarse de forma transparente para cada usuario restante sin ninguna intervención de su parte.
Parece que la principal preocupación sería cambiar para asegurar que los canales de comunicación cliente-servidor fueran seguros y que el cliente pueda mantener sus secretos en secreto.