Pergunta

Não quero colocar senhas não criptografadas no arquivo de configuração do aplicativo.

Essa questão: Criptografando a senha do banco de dados em application.conf tem uma ótima solução para o problema, mas funciona apenas para o Play 1.

Alguém conhece uma solução que funcione para o Play 2.0?Estou usando anorm na versão Scala do Play 2.0.2.

Foi útil?

Solução 3

Graças à discussão com Raffaele e seguindo minha própria investigação do código, parece que o Play 2.0 não permite criptografar senhas de banco de dados.

Se eu perdi alguma coisa, por favor me avise.

EDITAR:Pode-se contornar o problema usando o driver de banco de dados personalizado da seguinte maneira:

// 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)= ...
}

então você substitui application.conf/db..driver pelo driver my.com.MyDecrypting.Não é perfeito, mas funciona para mim...

Outras dicas

Todos os esforços são inúteis. Quando colocamos a senha do Hashed em um banco de dados é porque os humanos podem reter senhas em seus cérebros, e seus cérebros não são legíveis . É chamado criptografia assimétrica .

A coisa que você está falando só é possível com Simétrica Criptografia: O programa tem a chave no tempo de execução e usa essa chave para descriptografar a senha do banco de dados. Mas qual é o ponto de armazenar a senha do banco de dados criptografada com uma chave, e ainda assim ter essa chave disponível publicamente? (Isso é verdade para fontes Java e classes compiladas). Uma corrente é tão forte quanto sua ligação mais fraca.

Quando uma máquina precisa se conectar a um dB, ele precisa de uma senha: Nós armazenamos essa senha em texto simples porque o programa deve usá-lo como é, e nenhuma entrada humana é necessária . Tudo o que podemos fazer para impor a segurança é restringir o acesso a este arquivo de texto simples, eventualmente protegendo-o com uma senha armazenada apenas na mente do administrador (BTW, mais provável que o administrador mantenha todas as suas senhas em um banco de dados, talvez com um senha mestra). Note que as coisas não mudam se você usar o plugin mencionado.

A única outra coisa que vem à minha mente é um aplicativo de reprodução que só se conecta ao banco de dados quando o administrador entrou na senha do banco de dados (mas realmente este é apenas um exercício de pensamento)

Eu sei que é um pouco tarde, mas não há discussões mais recentes sobre esse problema.Quero compartilhar a solução real (Play v.2.5.X), conforme sugerido em documentação, agora é possível substituir o GuiceApplicationLoader para configurar o GuiceApplicationBuilder para processar de alguma forma as configurações iniciais.

Em uma nova aula 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)))
  }
}

Adicione também a application.config:

play.application.loader = "modules.ApplicationLoaderConfig"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top