Si el usuario puede leer su documento, pero usted no puede, entonces el usuario debe "saber" (es decir, recordar o almacenar) algún valor que usted no sepa. Un "valor" secreto que se usa para desbloquear el acceso a algunos documentos: los criptógrafos llaman a estos valores "claves".
Una contraseña es una clave que el usuario puede recordar, es decir, puede almacenarla en su cerebro. Esto tiene deficiencias, la principal de las cuales es que las contraseñas realistas son débiles contra la fuerza bruta. el hashing de contraseña adecuado se utiliza para tratar de hacer frente a esta debilidad . En cualquier caso, los usuarios pueden olvidar contraseñas.
Desde un punto de vista criptográfico, una forma "razonable" de hacer las cosas es la siguiente:
- Cada usuario tiene dos "contraseñas": una normal ( P ) y una "contraseña de recuperación" ( R ) que no es realmente una contraseña, ya que es una gran secuencia de letras aleatorias, y el usuario no intentará recordarla.
- El usuario escribe la contraseña de recuperación en un trozo de papel que almacena en un lugar seguro (por ejemplo, en un banco). La contraseña de recuperación está ahí para recuperar los datos cuando el usuario olvida su contraseña.
- Cada archivo está cifrado con una clave simétrica K , llamada "clave maestra" (cada usuario tiene su propia "clave maestra").
- El sistema de almacenamiento, donde están los documentos, también contiene el cifrado de K por P , y el cifrado de K por R . Cuando se encripta "por la contraseña P ", quiero decir que se utiliza una sal aleatoria específica del usuario en una buena función de hashing de contraseña para convertir P en una clave simétrica K P , y esa clave simétrica se usa para cifrar K . De manera similar con R .
Cuando el usuario desea leer sus documentos, ingresa a P , de donde se deriva KP (usando la sal almacenada); esto permite recuperar K y, por lo tanto, descifrar los documentos.
Cuando el usuario cambia su contraseña a P ', basta con recuperar K (como arriba), generar una nueva sal, luego calcular K P ' , encripta K con eso, y almacena el resultado (junto con el nuevo salt) en el servidor.
Cuando el usuario olvida su contraseña, va a su banco, recupera su contraseña de recuperación R y la usa para recuperar K y luego elige una nueva contraseña.
Con lo anterior, el servidor de almacenamiento sysadmin puede obtener suficiente información para "probar contraseñas" (lo que se denomina "ataque de diccionario sin conexión"). Esto es inevitable, y es por eso que usamos una buena función de hashing de contraseñas con sales y muchas iteraciones.
Como lo indica @ scuzzy-delta, un punto crítico es que el cliente no es un desarrollador, por lo que necesariamente tendrá que confiar en algún software, en algún momento, no jugarle trucos desagradables. Esto cubre su aplicación, pero también el sistema operativo; y, más generalmente, será responsabilidad del cliente asegurarse de que su PC no esté cargada de malware. Bajo estas condiciones, no puede garantizar que los documentos del cliente no serán saqueados; pero puede asegurarse de que no se lo culpará si le auditan el código (recuerde que sus clientes son abogados: pueden ser feroces). La auditoría es muy costosa, y cada vez más si el código es más grande, por lo que desea mantener su aplicación lo más pequeña posible.
Se sabe que la criptografía es difícil de implementar, por lo que se recomienda ampliamente que se adhiera a los formatos estándar existentes y, si es posible, a las bibliotecas estándar. El formato OpenPGP sería un buen lugar para comenzar. Lo ideal sería encontrar un buen formato implementado tanto por Android como por iOS (el código que ya está en el teléfono no necesita ser auditado, al menos no para la auditoría que cubre su propia máscara).