En mi aplicación Rails, los usuarios envían combinaciones de nombre de usuario / contraseña sensibles a sus sistemas de tienda web para que mi aplicación pueda interactuar con ellos. Necesito hacer cumplir una alta seguridad de datos en reposo para estos datos.
De lo que leí en e.g. esta respuesta la attr_encrypted gem es una buena solución para cifrar campos de modelo en MongoDB. Pero no me gusta el hecho de que la funcionalidad, así como los datos y las claves cifradas, se manejan / almacenan en un solo servidor. Y me gustaría usar una clave única para cada cifrado. Así que estoy considerando almacenar los nombres de usuario en un servidor, las contraseñas encriptadas en un segundo y las claves en un tercero.
¿Ve alguna bandera roja en este enfoque?
Así es como manejo el envío de usuarios de una nueva tienda web:
1) Mi servidor principal recibe datos de la tienda web de un usuario y guarda el username
, pero reenvía el password
:
def create_webshop
webshop = current_user.webshops.create(username: params[:username])
HTTParty.get("https://passwords.mydomain.com/create_password?password=#{params[:password]}&webshop_id=#{webshop._id}")
end
2) Mi servidor de contraseñas recibe el password
y genera un key
. Luego encripta el password
y lo guarda, pero reenvía el key
:
def create_password
key = SecureRandom.base64
password = AESCrypt.encrypt(params[:password], key)
password_holder = PasswordHolder.create(webshop_id: params[:webshop_id], password: password)
HTTParty.get("https://keys.mydomain.com/create_key?password_holder_id=#{password_holder._id}&key=#{key}")
render :json => {}, :status => :ok
end
3) Mi servidor de claves recibe el key
y lo guarda:
def create_key
KeyHolder.create(password_holder_id: params[:password_holder_id], key: params[:key])
render :json => {}, :status => :ok
end
Así es como obtengo la contraseña para una tienda web:
1) Mi servidor principal consulta el password
a un determinado webshop_id
:
def get_password(webshop)
password_response = HTTParty.get("https://passwords.mydomain.com/get_password?webshop_id=#{webshop._id}")
password = JSON.parse(password_response.body)["password"]
# Do stuff...
end
2) Mi servidor de contraseñas recibe la consulta de la contraseña y consulta el key
a un password_id
dado:
def get_password
password_holder = PasswordHolder.where(webshop_id: params[:webshop_id]).first
key_response = HTTParty.get("https://keys.mydomain.com/get_key?password_holder_id=#{password_holder_id._id}")
key = JSON.parse(key_response.body)["key"]
password = AESCrypt.decrypt(password_holder.password, key)
render :json => {:password => password}, :status => :ok
end
3) Mi servidor de claves recibe la consulta de claves y devuelve el key
:
def get_key
render :json => {:key => KeyHolder.where(password_holder_id: params[:password_holder_id]).first.key}, :status => :ok
end
Mi servidor de contraseñas luego desencripta el password
y lo devuelve a mi servidor principal .