quinta-feira, 31 de março de 2016

Guardando senhas criptografadas em Java

Fonte: http://blog.caelum.com.br/guardando-senhas-criptografadas-em-java/


Eu e o Thiago Ferreira estavámos mais uma vez na Caelum passando pela situação de gravar as senhas do usuário no banco de dados. Ainda hoje alguns grandes sites cometem o grave erro de guardar as senhas dos usuários em texto puro, fazendo com que um possível roubo de dados acarrete num problema ainda maior.
O processo clássico é guardar um hash (chamado também de digest nesse caso) da senha do usuário, usando algum algoritmo de hash unidirecional. Isso pode ser feito utilizando uma chamada de função na query do banco de dados (como MD5()no MySQL), ou, o mais utilizado para não ter de trafegar a senha entre o servidor web e o banco de dados: com o MessageDigest dojavax.security. Através dessa classe você pode facilmente gerar o hash de uma senha:
MessageDigest algorithm = MessageDigest.getInstance("MD5");
byte messageDigest[] = algorithm.digest("senha".getBytes("UTF-8"));
Agora temos um array de bytes que podemos guardar no banco de dados. Quando o usuário logar, basta digerirmos novamente a senha colocada no formulário web, e comparar o hash resultante com o que há no banco. Você poderia guardar esse array de byte como uma String fazendo new String(bytes, encoding), porém muito mais usual é guardar os hexadecimais desses bytes dentro de uma String:
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
  hexString.append(String.format("%02X", 0xFF & b));
}
String senha = hexString.toString();
Isso gerará e8d95a51f3af4a3b134bf6bb68a213a.
Apesar de muito usado, o MD5 já é considerado um algoritmo de hash quebrado, pois hoje em dia podemos rapidamente, através de força bruta, descobrir uma String que gere o mesmo hash, já que neste algoritmo ocorrem mais colisões do que o que foi inicialmente imaginado por seus criadores. Muitos passaram a usar o SHA-1, porém este já da sinais de que, num futuro próximo, será quebrado com força bruta. O próprio governo americano já evita utilizar a família SHA-1, priorizando o uso do SHA-2. Logo, o procedimento completo mais adequado atualmente seria usar algo como:
MessageDigest algorithm = MessageDigest.getInstance("SHA-256");
byte messageDigest[] = algorithm.digest(original.getBytes("UTF-8"));
 
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
  hexString.append(String.format("%02X", 0xFF & b));
}
String senha = hexString.toString();
Para tornar seu sistema ainda mais seguro em relação as senhas guardadas, pode-se ainda adicionar salts, mais iterações de hash e outras técnicas que tornaria ainda mais difícil um possível ataque de força bruta contra uma base de dados roubada, se protegendo também contra o provável uso de senhas fracas por parte de seus usuários. 

quarta-feira, 30 de março de 2016

JPA 2.1 – 12 features every developer should know

Fonte: http://www.thoughts-on-java.org/jpa-21-overview/


JPA 2.1 – 12 features every developer should know

If you are a regular reader of this blog, you know that I wrote several articles about features and enhancements introduced with JPA 2.1. One thing that was missing, was a general overview about all the changes. So here it is :-)
The following paragraphs provide a description of the 12 features and enhancements introduced with JPA 2.1. And as a special bonus, I created a cheat sheet with a short description and additional code snippets for each change, which you can download for free.

Features and Enhancements in JPA 2.1

Named Stored Procedure Query

Sometimes it is easier or more efficient to use a stored procedure to perform the operations within the database. Before JPA 2.1 the only way to call a stored procedure was to use a native query. The newly introduced @NamedStoredProcedureQuery can now be used to annotate a query to call the stored procedure.
I described this in more details in How to call stored procedures in JPA.

Stored Procedure Query

The Stored Procedure Query is an alternative way to implement a stored procedure call without using annotations. For this purpose the EntityManager was extended by the createStoredProcedureQuery(String procedureName, Class… resultClasses) method.
You can read more about it in How to call stored procedures in JPA – Part 2.

Attribute Converter

Attribute Converter provide a nice and easy way to define a custom mapping between your property on the entity and the database column. The only thing that is needed is a class that implements the AttributeConverter interface and is annotated with @Converter. You can find a more detailed introduction to Attribute Converter in JPA 2.1 – How to implement an Attribute Converter.
One of the most obvious ways to use an Attribute Converter is to implement a custom type mapping to persist a not supported data type like the new Java Date and Time API:  How to persist LocalDate and LocalDateTime with JPA.
Or you can use it to change an existing default mapping, as it was done in JPA 2.1 Attribute Converter – The better way to persist enums.
You could also keep the type and change the stored value to implement some business requirements like encryption: How to use a JPA Attribute Converter to encrypt your data.

Constructor Result Mapping

The @ConstructorResult annotation is a handy addition to the already existing @SqlResultSetMapping and can be used to map the result of a query to a constructor call.
You can read more about it in the constructor result mappings part of the result set mapping series.

Programmatic Named Queries

Before JPA 2.1 the @NamedQuery annotation was the only way to define named queries. A programmatic creation was not supported. This was changed with JPA 2.1. The EntityManager now provides the addNamedQuery(String name, Query query) method to do this.

Named Entity Graph

Lazy loading of relations between entities is a common pattern to load only the required information from the database and to improve the performance of the application. While this is a great feature as long as the related entities are not required, it creates additional load when the relations need to be initialized. There are multiple ways to initialize these lazy relations and using Named Entity Graphs is one of the better ones. 
The annotations @NamedEntityGraph@NamedAttributeNode and @NamedSubGraph allow us to define a graph of entities that will be loaded from the database. You can find a more detailed description on how to do this in JPA 2.1 Entity Graph – Part 1: Named entity graphs.

Entity Graph

Entity Graphs are the second option introduced with JPA 2.1 to define a graph of entities that shall be loaded from the database and their usage is similar to Named Entity Graphs. The only difference is that Entity Graphs are defined via a Java API and not via annotations. Therefore theEntityManager was extended by the createEntityGraph(Class rootType) method. This is explained in more detail in JPA 2.1 Entity Graph – Part 2: Define lazy/eager loading at runtime.

JPQL Enhancements

There were several enhancements to the JPQL which can come in handy. You can now use the keyword ON to define additional join parameters, call database functions by using FUNCTION and downcast entities with TREAT.

Criteria API Bulk Operations

Up to JPA 2.1 the Criteria API did not provide any support for update or delete operations. The only options available were to perform the update on an entity or to write a native query to update multiple records at once. As described in Criteria Update/Delete – The easy way to implement bulk operations with JPA2.1, the Criteria API was extended with CriteriaUpdate andCriteriaDelete to also support bulk write operations.

Unsynchronized Persistence Context

Using a synchronized persistence context to propagate every change to the database is the default approach in JPA. If you need more control about the database propagation, you can now use the unsynchronized persistence context. Therefore you need to provide the synchronization mode to the injection with @PersistenceContext(synchronization=SynchronizationType.UNSYNCHRONIZED). You then need to call EntityManager.joinTransaction() manually to synchronize the changes.

Generating DB Schema

Up to JPA 2.1 you needed to use vendor specific configuration parameter to define the database setup in the persistence.xml file. Starting from version 2.1 there is also a standard way to do this. Therefore the specification defines the following long list of parameters:
  • javax.persistence.schema-generation.database.action
  • javax.persistence.schema-generation.scripts.action
  • javax.persistence.schema-generation.create-source
  • javax.persistence.schema-generation.drop-source
  • javax.persistence.schema-generation.create-database-schemas
  • javax.persistence.schema-generation.scripts.create-target
  • javax.persistence.schema-generation.scripts.drop-target
  • javax.persistence.database-product-name
  • javax.persistence.database-major-version
  • javax.persistence.database-minor-version
  • javax.persistence.schema-generation.create-script-source
  • javax.persistence.schema-generation.drop-script-source
  • javax.persistence.schema-generation.connection
  • javax.persistence.sql-load-script-source
You can get a more detailed description of the different parameters and some examples how to use them to setup your database in Standardized schema generation and data loading with JPA 2.1.

CDI-Support in Entity Listener

The integration with CDI was improved with JPA 2.1. You can now use CDI to inject beans intoEntityListeners and to implement the @PreDestroy and @PostConstruct methods.

To sum it up

From my point of view, JPA 2.1 – despite being just a minor release – introduced some great improvements to the specification. I especially like the entity graphs and the stored procedure queries but also the AttributeConverter can be quite handy. Which features do you like best?
Sometimes it is difficult to remember all the implementation details, if you need them. This is where I personally like to have a cheat sheet that provides all the information I need, like this one 😉

How to persist LocalDate and LocalDateTime with JPA

Fonte: http://www.thoughts-on-java.org/persist-localdate-localdatetime-jpa/

How to persist LocalDate and LocalDateTime with JPA

All these issues are gone with Java 8. The new Date and Time API is well designed, easy to use and (finally) immutable. The only issue that remains is, that you cannot use it with JPA.
Well, that’s not completely correct. You can use it, but JPA will map it to a BLOB instead of aDATE or TIMESTAMP. That means the database is not aware of the date object and cannot apply any optimization for it. That’s not the way we should or want to do it.

Why does JPA not support LocalDate and LocalDateTime?

The answer is simple, JPA 2.1 was released before Java 8 and the Date and Time API simply didn’t exist at that point in time. Therefore the @Temporal annotation can only be applied to attributes of type java.util.Date and java.util.Calendar.
If you want to store a LocalDate attribute in a DATE column or a LocalDateTime in aTIMESTAMP column, you need to define the mapping to java.sql.Date or java.sql.Timestampyourself. Thanks to the attribute converter, one of several new features in JPA 2.1, this can be achieved with just a few lines of code.
In the following examples, I will show you how to create an attribute converter for LocalDateand LocalDateTime. If you want to learn more about attribute converter, have a look at How to implement a JPA 2.1 Attribute Converter or one of the other usage examples like a better way to persist enums or encrypting data.
The most important things you need to remember about attribute converter are also described in the free “New Features in JPA 2.1” cheat sheet.

The example

Before we create the attribute converters, lets have a look at the example entity for this post.
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column
private LocalDate date;
@Column
private LocalDateTime dateTime;
...
}
view rawMyEntity.java hosted with ❤ by GitHub
Attribute converter are part of the JPA 2.1 specification and can therefore be used with any JPA 2.1 implementation, e.g. Hibernate or EclipseLink. I used Wildfly 8.2 with Hibernate 4.3 for the following examples.   

Converting LocalDate

As you can see in the following code snippet, there isn’t much you need to do to create an attribute converter for LocalDate.
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
You need to implement the AttributeConverter<LocalDate, Date> interface with its two methods convertToDatabaseColumn and convertToEntityAttribute. As you can see on the method names, one of them defines the conversion from the type of the entity attribute (LocalDate) to the database column type (Date) and the other one the inverse conversion. The conversion itself is very simple because java.sql.Date already provides the methods to do the conversion to and from a LocalDate.
Additionally the attribute converter needs to be annotated with the @Converter annotation. Due to the optional autoApply=true property, the converter will be applied to all attributes of typeLocalDate. Have a look here, if you want to define the usage of the converter for each attribute individually.
The conversion of the attribute is transparent to the developer and the LocalDate attribute can be used as any other entity attribute. You can use it as a query parameter for example.
LocalDate date = LocalDate.of(2015, 8, 11);
TypedQuery<MyEntity> query = this.em.createQuery("SELECT e FROM MyEntity e WHERE date BETWEEN :start AND :end", MyEntity.class);
query.setParameter("start", date.minusDays(2));
query.setParameter("end", date.plusDays(7));
MyEntity e = query.getSingleResult();
view rawQuery.java hosted with ❤ by GitHub

Converting LocalDateTime

The attribute converter for LocalDateTime is basically the same. You need to implement theAttributeConverter<LocalDateTime, Timestamp> interface and the converter needs to be annotated with the @Converter annotation. Similar to the LocalDateConverter, the conversion between a LocalDateTime and an java.sql.Timestamp is done with the conversion methods ofTimestamp
@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
}
}

Conclusion

JPA 2.1 was released before Java 8 and therefore doesn’t support the new Date and Time API. If you want to use the new classes (in the right way), you need to define the conversion tojava.sql.Date and java.sql.Timestamp yourself. This can be easily done by implementing the AttributeConverter<EntityType, DatabaseType> interface and annotating the class with@Converter(autoApply=true). By setting autoApply=true, the converter will be applied to all attributes of the EntityType and no changes on the entity are required.
As far as I know, the next JPA release will support the Date and Time API and the different implementations will probably support it even earlier. Hibernate 5 for example will support it as a proprietary feature.
If you want to learn more about the new features in JPA 2.1, have a look at the JPA 2.1 Overviewand get your free “New Features in JPA 2.1” cheat sheet.