¿Estrategias seguras de cifrado y almacenaje de datos?

165 views
Skip to first unread message

FreeMEM

unread,
Mar 14, 2013, 10:40:05 AM3/14/13
to web2py-usuarios
Necesito almacenar datos encriptados en una tabla y que se puedan desencriptar. Hay muchas soluciones para hacer esto, desde usar al propio MySQL para esto con ENCRYPT/DECRYPT, hasta hacerlo desde python. El problema en todas las situaciones es que tengo que disponer de la clave para cifrar/descifrar el dato por lo que si lo hardcodeo en el código y alguien logra acceder por shell a mi servidor (es decir, que me lo hackean), tengo los datos vendidos.

Tengamos por ejemplo que queremos subir un fichero, pero queremos almacenarlo cifrado sin que desde el servidor pueda desencriptarlo. Para evitar el problema de que me comprometan el servidor, se me ocurrió cifrar el fichero desde el navegador con una función en javascript que me quedó bastante bien, en la que el usuario pusiese la pass para cifrar y descifrar de tal modo que los datos llegasen cifrados. Esto es muy seguro pero cada vez que el usuario necesita obtener el fichero, el usuario se ve obligado a dar el pass, algo bastante incómodo.

Otro caso es por ejemplo almacenar los datos de usuario y contraseña de un servidor de correo remoto. En este caso os pongo de ejemplo un trozo de código de un proyecto que tengo en el que almaceno user y pass de la cuenta de un usuario ajeno a mi servicio en un servidor de correo ajeno también. 


# -*- coding: utf-8 -*-
from gluon import *
from gluon.dal import SQLCustomType
import logging, datetime, m2secret, hashlib
from applications.ejemplo.modules.settings import Settings
logger = logging.getLogger(" >>>> modules/adminsettings >>>> tuvozlegal: ")
logger.setLevel(logging.DEBUG)

class Cifrar:

def __init__(self):
self.key= hashlib.sha256("password").digest()
def __call__(self,value):
secret = m2secret.Secret()
secret.encrypt(value, self.key)
return secret.serialize()
def formatter(self,value):
secret = m2secret.Secret()
secret.deserialize(value)
return (secret.decrypt(self.key), None)


class Adminsettings(object):

def __init__(self, db):
self.db=db

def define_tables(self):
config=Settings()
data= Cifrar()
cryp = SQLCustomType(type ='text', native ='longtext', encoder =(lambda x: data(x)), decoder = (lambda x: data.formatter(x)[0] ))
self.db.define_table('adminsettings',
Field('mailserver', 'string'),
Field('username', 'string', length=128, requires=IS_NOT_EMPTY(error_message="No puede estar vacío")),
Field('password', type=cryp, length=256, readable=False, label='Password'),
Field('emailfrom', 'string', length=128, requires=IS_EMAIL(error_message="Formato de email incorrecto")),
Field('blogitems', 'integer', default=20),
Field('messageitems', 'integer', default=15),
Field('bloglistitems', 'integer', default=15),
Field('useritems', 'integer', default=15),
Field('subscriptionitems', 'integer', default=15),
migrate=config.settings['migrate'])



Si veis la clase Cifrar en la línea "self.key= hashlib.sha256("password").digest()" está el password hardcoded para poder cifrar y descifrar la pass del servicio remoto en la base de datos. Aunque el dato está almacenado de un modo seguro, si me logueo en el server y tengo acceso al código fuente de la aplicación se puede ver el password que sirve para descifrar el dato :-( así que sigo vendido en caso de intrusión.

Existe alguna estrategia para solventar esto?

Un saludo




Luis Díaz

unread,
Mar 14, 2013, 11:11:44 AM3/14/13
to web2py-...@googlegroups.com
tengo los siguientes enlaces que te pueden dar mas ideas:

http://crypto.stanford.edu/sjcl/
http://bitwiseshiftleft.github.com/sjcl/doc/
http://bitwiseshiftleft.github.com/sjcl/demo/

http://www.clipperz.com/open_source/javascript_crypto_library


yo usaría un mecanismo auxiliar para autentificar a los usuarios.. puede ser
facebook o gmail.
y luego si les pediría una cadena de texto para descifrar la data almacenada.
> --
> Has recibido este mensaje porque estás suscrito al grupo "web2py-usuarios"
> de Grupos de Google.
> Para anular la suscripción a este grupo y dejar de recibir sus correos
> electrónicos, envía un correo electrónico a
> web2py-usuari...@googlegroups.com.
> Para obtener más opciones, visita https://groups.google.com/groups/opt_out.
>
>



--
Díaz Luis
Analista Programador Facultad de Odontología UC
User Linux 532223

freemem

unread,
Mar 14, 2013, 12:50:12 PM3/14/13
to web2py-...@googlegroups.com


yo usaría un mecanismo auxiliar para autentificar a los usuarios.. puede ser
facebook o gmail.
y luego si les pediría una cadena de texto para descifrar la data almacenada.



Para subir ficheros ya cifrados desde el navegador uso una solución basada en esto


Creo que es la misma idea que me has pasado en los enlaces, pero cada vez que hay que cifrar/descifrar el usuario tiene que meter la clave y es la solución que estoy intentando evitar.

Alan Etkin

unread,
Mar 14, 2013, 1:13:54 PM3/14/13
to web2py-...@googlegroups.com
web2py viene con el validador especial CRYPT que (según entiendo) cifra y recupera los datos ingresados. Lo utiliza para las contraseñas, pero podrías personalizarlo para cualquier campo.

http://web2py.com/books/default/chapter/29/07?search=CRYPT%28#Validators

En cuanto a almacenar datos en el servidor que no se puedan desencriptar en el mismo servidor, quizás no entendí bien, pero creo que es imposible. Si un usario tiene acceso irrestricto al servidor, entonces puede acceder a los datos almacenados pero también a los parámetros para leer los datos cifrados. Supongo que para impedir esto tendrías que encriptar y desencriptar del lado del cliente sin informar los parámetros.
Reply all
Reply to author
Forward
0 new messages