Pregunta

No quiero poner contraseñas no cifradas en el archivo de configuración de la aplicación.

Esta pregunta: Cifrar la contraseña de la base de datos en application.conf tiene una gran solución para el problema pero solo funciona para Play 1.

¿Alguien conoce una solución que funcione para Play 2.0?Estoy usando anorm en la versión Scala de Play 2.0.2.

¿Fue útil?

Solución 3

Gracias a la discusión con Raffaele y después de mi propia investigación del Código, parece que Play 2.0 no le permite encriptar contraseñas de DB.

Si me perdí algo, por favor, hágamelo saber.

Editar : uno puede funcionar alrededor del problema mediante el uso del controlador de base de datos personalizado de la siguiente manera:

// Just redirect everything to the delegate
class DelegatingDriver(delegate: Driver) extends Driver
{
  def connect(url: String, info: Properties) = delegate.connect(url, info)
  def acceptsURL(url: String) = delegate.acceptsURL(url)
  def getPropertyInfo(url: String, info: Properties) = delegate.getPropertyInfo(url, info)
  def getMajorVersion = delegate.getMajorVersion
  def getMinorVersion = delegate.getMinorVersion
  def jdbcCompliant() = delegate.jdbcCompliant()
}

// Replace password in properties with the decrypted one
class MyDecryptingDriver extends DelegatingDriver(Class.forName("<my.original.Driver>").newInstance().asInstanceOf[Driver])
{
  override def connect(url: String, info: Properties)= {
    // copy Properties
    val overriddenProperties= clone(info)   
    // override password property with the decrypted value
    Option(info.getProperty("password")).foreach(value => overriddenProperties.setProperty("password", decryptPassword(value)))
    super.connect(url, overriddenProperties)
  }

  def clone(orig: Properties)= {
    val result= new Properties()
    orig.propertyNames().map(_.asInstanceOf[String]).foreach(pName => result.setProperty(pName, orig.getProperty(pName)))
    result
  }

  def decryptPassword(encrypted: String)= ...
}

luego reemplaza a aplicar.conf / db..driver por My.com.MyDecrypting Driver.No es perfecto, pero funciona para mí ...

Otros consejos

Todos los esfuerzos son inútiles. Cuando ponemos una contraseña de hash en una base de datos, ya que los humanos pueden conservar las contraseñas en sus cerebros, y sus cerebros no son legibles . Se llama asymmetric cifrado.

La cosa que está hablando solo es posible con Sypetric Cifrado: el programa tiene la clave en tiempo de ejecución y usa esta clave para descifrar la contraseña de DB. Pero, ¿cuál es el punto en almacenar la contraseña de DB cifrada con una tecla, y aún está disponible públicamente esta clave? (Esto es cierto tanto para las fuentes de Java como para las clases compiladas). Una cadena es tan fuerte como su enlace más débil.

Cuando una máquina tiene que conectarse a un DB, necesita una contraseña: almacenamos esta contraseña en texto sin formato porque el programa debe usarlo como está, y no se requiere ninguna entrada humana . Todo lo que podemos hacer para hacer cumplir la seguridad es restringir el acceso a este archivo de texto simple, lo que eventualmente lo protege con una contraseña almacenada solo en la mente del administrador (por cierto, más probable que el administrador mantendrá todas sus contraseñas en una base de datos, tal vez con un contraseña maestra). Tenga en cuenta que las cosas no cambian si usa el complemento de reproducción mencionado.

La única otra cosa que viene a mi mente es una aplicación de juego que solo se conecta al DB cuando el administrador ingresa la contraseña de DB (pero realmente esto es solo un ejercicio de pensamiento)

Sé que es un poco tarde, pero no hay discusiones más recientes sobre este problema.Quiero compartir la solución real (Play v.2.5.X), como se sugiere en documentación, ahora es posible anular el GuiceApplicationLoader para configurar el GuiceApplicationBuilder para procesar de alguna manera las configuraciones iniciales.

en una nueva clase modules/ApplicationLoaderConfig.scala:

import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import javax.xml.bind.DatatypeConverter

import play.api.inject.guice._
import play.api.{ApplicationLoader, Configuration}

class ApplicationLoaderConfig extends GuiceApplicationLoader() {

  override def builder(context: ApplicationLoader.Context): GuiceApplicationBuilder = {

    // Decrypt secrets
    val decryptedConfig = context.initialConfiguration ++
      Configuration("config.to.descrypt.1" -> decryptDES(context.initialConfiguration.getString("config.to.descrypt.1").get)) ++
      Configuration("config.to.descrypt.2" -> decryptDES(context.initialConfiguration.getString("config.to.descrypt.2").get))

    initialBuilder
      .in(context.environment)
      .loadConfig(decryptedConfig)
      .overrides(overrides(context): _*)
  }

  private def decryptDES(secret: String): String = {
    val key = "12345678"
    val skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "DES")

    val cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")
    cipher.init(Cipher.DECRYPT_MODE, skeySpec)

    new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(secret)))
  }
}

Añadir también a application.config:

play.application.loader = "modules.ApplicationLoaderConfig"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top