Criptografar a senha do persistence.xml
Olá pessoal, recemente desenvolvi uma aplicação para desktop utilizando JPA+Hibernate, porém observei que é necessario informar no arquivo persistence.xml o usuario e a senha do banco de dados. E ai esta o meu problema, quando eu for destribuir a aplicação qualquer pessoa poderá abrir o meu jar e visualizar o arquivo persistence.xml, e assim terá a senha do meu BD .
Já pesquisei bastante na web, mas ainda não encontrei nada, o mais proximo que consegui foi ouvir falar sobre uma API chamada jasypt, que serve para criptografar senhas, e até onde consegui entender é possivel utilizando ela colocar a senha do BD criptografada no arquivo persistence.xml. Porém não consigo fazer isso de maneira alguma !!!
Alguém sabe utilizar esta API, ou então sabe de outra forma de resolver isto?
Desde já obrigado !!!
Já pesquisei bastante na web, mas ainda não encontrei nada, o mais proximo que consegui foi ouvir falar sobre uma API chamada jasypt, que serve para criptografar senhas, e até onde consegui entender é possivel utilizando ela colocar a senha do BD criptografada no arquivo persistence.xml. Porém não consigo fazer isso de maneira alguma !!!
Alguém sabe utilizar esta API, ou então sabe de outra forma de resolver isto?
Desde já obrigado !!!
Rafael Costa
Curtidas 0
Respostas
Davi Costa
14/09/2010
Rafael,
existe algumas formas de fazer a conexão
que não use o persistence.xml.
Se tiver usando o hibernate pode fazer uma classe assim:
//imports omitidos
public class HibernateUtil {
private static final long serialVersionUID = 1L;
private static HibernateUtil me;
private SessionFactory sessionFactory;
/**
* Construtor padrão
*
* @author Costa
* @version 1.0,
*/
private HibernateUtil(){
sessionFactory = new AnnotationConfiguration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver")
.setProperty("hibernate.connection.url", "jdbc:postgresql://192.168.0.150:5432/DBSCS")
.setProperty("hibernate.connection.username", "postgres")
.setProperty("hibernate.connection.password", "postgres")
.setProperty("hibernate.hbm2ddl.auto", "none")
.setProperty("hibernate.show_sql", "true")
.setProperty("hibernate.format_sql", "true")
.setProperty("hibernate.c3p0.acquire_increment", "1")
.setProperty("hibernate.c3p0.idle_test_period", "100")
.setProperty("hibernate.c3p0.max_size", "10")
.setProperty("hibernate.c3p0.max_statements", "0")
.setProperty("hibernate.c3p0.min_size", "5")
.setProperty("hibernate.c3p0.timeout", "100")
//.addAnnotatedClass(Clientes.class) aqui vc declara todas suas classes da camada modelo
.buildSessionFactory();
}
public Session getSession() {
Session toReturn = sessionFactory.openSession();
toReturn.beginTransaction();
return toReturn;
}
public static HibernateUtil getInstance() {
if (me== null){
me = new HibernateUtil();
}
return me;
}
}
Percebeu que eu passei password direto "postgres".
Ai vc pode ver alguma biblioteca Java que receba esse valor criptografado te retorne a String com um valor
real ("postgres").
Acredito que até o jasypt que vc já pesquisou resolva.
Espero ter ajudado
Att Davi
existe algumas formas de fazer a conexão
que não use o persistence.xml.
Se tiver usando o hibernate pode fazer uma classe assim:
//imports omitidos
public class HibernateUtil {
private static final long serialVersionUID = 1L;
private static HibernateUtil me;
private SessionFactory sessionFactory;
/**
* Construtor padrão
*
* @author Costa
* @version 1.0,
*/
private HibernateUtil(){
sessionFactory = new AnnotationConfiguration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver")
.setProperty("hibernate.connection.url", "jdbc:postgresql://192.168.0.150:5432/DBSCS")
.setProperty("hibernate.connection.username", "postgres")
.setProperty("hibernate.connection.password", "postgres")
.setProperty("hibernate.hbm2ddl.auto", "none")
.setProperty("hibernate.show_sql", "true")
.setProperty("hibernate.format_sql", "true")
.setProperty("hibernate.c3p0.acquire_increment", "1")
.setProperty("hibernate.c3p0.idle_test_period", "100")
.setProperty("hibernate.c3p0.max_size", "10")
.setProperty("hibernate.c3p0.max_statements", "0")
.setProperty("hibernate.c3p0.min_size", "5")
.setProperty("hibernate.c3p0.timeout", "100")
//.addAnnotatedClass(Clientes.class) aqui vc declara todas suas classes da camada modelo
.buildSessionFactory();
}
public Session getSession() {
Session toReturn = sessionFactory.openSession();
toReturn.beginTransaction();
return toReturn;
}
public static HibernateUtil getInstance() {
if (me== null){
me = new HibernateUtil();
}
return me;
}
}
Percebeu que eu passei password direto "postgres".
Ai vc pode ver alguma biblioteca Java que receba esse valor criptografado te retorne a String com um valor
real ("postgres").
Acredito que até o jasypt que vc já pesquisou resolva.
Espero ter ajudado
Att Davi
GOSTEI 0
Rafael Costa
14/09/2010
Olá Davi, primeiramente muito obrigado por responder, mas isso não faz o que eu queria,
pois utilizando JPA tem como eu passar a senha pela aplicação também, fazendo assim:
Properties prop = new Properties();
prop.setProperty("hibernate.connection.password", "mypassword");
final EntityManagerFactory factory = Persistence.createEntityManagerFactory("unit",prop);
Desta maneira eu não preciso colocar a senha no arquivo persistence.xml, mas mesmo assim qualquer um com um programinha simples de converter .class em .java (JAD por exemplo) poderá ver meu codigo java e assim ele verá minha senha do BD da mesma forma.
Mas estive pensando, acho que então não tem como, porque de qualquer forma eu tenho que colocar a senha descriptografada em algum lugar, e não tem como eu impedir de alguém ver essa senha. :( Ou será que estou enganado ?
Mas de qualquer forma, valeu pela ajuda ! :D
pois utilizando JPA tem como eu passar a senha pela aplicação também, fazendo assim:
Properties prop = new Properties();
prop.setProperty("hibernate.connection.password", "mypassword");
final EntityManagerFactory factory = Persistence.createEntityManagerFactory("unit",prop);
Desta maneira eu não preciso colocar a senha no arquivo persistence.xml, mas mesmo assim qualquer um com um programinha simples de converter .class em .java (JAD por exemplo) poderá ver meu codigo java e assim ele verá minha senha do BD da mesma forma.
Mas estive pensando, acho que então não tem como, porque de qualquer forma eu tenho que colocar a senha descriptografada em algum lugar, e não tem como eu impedir de alguém ver essa senha. :( Ou será que estou enganado ?
Mas de qualquer forma, valeu pela ajuda ! :D
GOSTEI 0
Davi Costa
14/09/2010
Rafael,
vejo uma pequena luz no fim do túnel,
seguindo essa estratégia q eu te passei.
No lugar de usar bibliotecas de terceiros,
já pensou em vc criar sua própria classe de utilitários para criptografar senhas.
Nessa classe cria um método estático que receba como parâmetro
uma String para vc não ter que instanciar essa classe
e diminuir o acoplamento.
Cria um código que só vc entenderia.
Posso até dar umas sugestões:
Vai fazendo tratamento de todos os caracteres que vc não quer receber,
por exemplo: ç~´.. entre outros.
Deixa sua lógica esperando todas as letras e números e que dependendo do
que receber como parâmetro ele sempre valores diferentes, por exemplo
e1 tem que retornar algo diferente de 1e .. e por aí vai.
Seria até interessante vc nessa classe utilitário (já que vc está bem preocupado com a segurança do banco)
em outro projeto vc mantém essa classe e deixa esse método bidirecional, para qdo vc for implantar seu projeto
em outros bancos vc saber que se "testeSenha" retorna "335dvdufbbf" então é só colocar
ClasseUtil.retornaSenha("335dvdufbbf") e vc vai ter certeza que vai retorna "testeSenha".
E pode manter esse método bidirecional somente no seu projeto a parte para ninguém executar ele
com "335dvdufbbf" e saber que vai retornar "testeSenha".
Espero ter ajudado.
att Davi
vejo uma pequena luz no fim do túnel,
seguindo essa estratégia q eu te passei.
No lugar de usar bibliotecas de terceiros,
já pensou em vc criar sua própria classe de utilitários para criptografar senhas.
Nessa classe cria um método estático que receba como parâmetro
uma String para vc não ter que instanciar essa classe
e diminuir o acoplamento.
Cria um código que só vc entenderia.
Posso até dar umas sugestões:
Vai fazendo tratamento de todos os caracteres que vc não quer receber,
por exemplo: ç~´.. entre outros.
Deixa sua lógica esperando todas as letras e números e que dependendo do
que receber como parâmetro ele sempre valores diferentes, por exemplo
e1 tem que retornar algo diferente de 1e .. e por aí vai.
Seria até interessante vc nessa classe utilitário (já que vc está bem preocupado com a segurança do banco)
em outro projeto vc mantém essa classe e deixa esse método bidirecional, para qdo vc for implantar seu projeto
em outros bancos vc saber que se "testeSenha" retorna "335dvdufbbf" então é só colocar
ClasseUtil.retornaSenha("335dvdufbbf") e vc vai ter certeza que vai retorna "testeSenha".
E pode manter esse método bidirecional somente no seu projeto a parte para ninguém executar ele
com "335dvdufbbf" e saber que vai retornar "testeSenha".
Espero ter ajudado.
att Davi
GOSTEI 0
Rafael Costa
14/09/2010
Valeu Davi, vou tentar fazer o que vc falou, caso não eu consiga eu volto aqui
Valeu, muito obrigado !!!
Valeu, muito obrigado !!!
GOSTEI 0