Préparer l'environnement de la démo:
Créer un projet maven sous eclipse avec les dépendances Jasypt :
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt-hibernate3</artifactId>
<version>1.9.0</version>
</dependency>
Ajouter les dépendances Bouncy Castle:
<!-- Bouncy castle --> <dependency> <groupId>bouncycastle</groupId> <artifactId>bcprov-jdk15</artifactId> <version>140</version> </dependency>
Configurer Spring:
<!-- Enccrypt JASYPT -->
<bean id="myStringEncryptor"
class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="providerName"><value>BC</value></property>
<property name="algorithm">
<value>PBEWITHSHA256AND128BITAES-CBC-BC</value>
</property>
<property name="password">
<value>jasypt</value>
</property>
</bean>
<!-- hibernate Encryptor for string -->
<bean id="theHibernateStringEncryptor"
class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor">
<property name="registeredName">
<value>myHibernateStringEncryptor</value>
</property>
<property name="encryptor">
<ref bean="myStringEncryptor" />
</property>
</bean>
Bien évidemment, la configuration de Spring n'est pas complète. Seule la partie qui nous concerne est présentée ici.
N'oublier pas de configurer les beans de Spring: dataSource, sessionFactory et transactionManager.
Sur le net on trouve facilement des tutoriaux sur le sujet.
Configurer l'entité Hibernate avec des annotations spécifiques:
@TypeDefs
({
@TypeDef (
name="encryptedString",
typeClass=EncryptedStringType.class,
parameters={
@Parameter(name="encryptorRegisteredName",
value="myHibernateStringEncryptor")
}
)
})
@Entity
public class Domaine implements Serializable{
private static final long serialVersionUID = 1L;
@Id private int id;
private String libelle;
private String description;
@Type(type="encryptedString")
private String ssn;
...
... getters / setters / toString omitted
Quelques explications :
L'annotation @TypeDef du package hibernate permet de définir un nouveau type,.
Dans notre démo c'est EncryptedStringType de Jasypt (org.jasypt.hibernate.type.EncryptedStringType).
L'attribut name, "encryptedString", de l'annotation @TypeDef permet d'annoter le (les) champs persistants à crypter/décrypter par Hibernate.
Dans notre cas, la classe entité, Domaine, possède une propriété nommée "ssn" de type String.
Cette propriété est annotée avec @Type(type="encryptedString") afin d'indiquer à Hibernate de la crypter/décrypter.
Aussi dans @DefType, l'attribut name de l'annotaion @Parameter d'hibernate établit le lien entre l'algorithme de cryptage enregistré dans la configuration de Spring.
Ecrire un test JUnit:
@Test public void testPersitColumnWithJasyptBC(){
ClassPathXmlApplicationContext springContext =
new ClassPathXmlApplicationContext("classpath:spring.xml");
<!-- add dynamincally BC provider -->
Security.addProvider(new BouncyCastleProvider());
IDomaineService domServ = (IDomaineService)
springContext.getBean("domaineService");
Domaine domaine=new Domaine();
domaine.setId(1);
domaine.setDescription("dommaine1 exemple");
domaine.setLibelle("dom1");
domaine.setSsn("ssn2crypte");
int pkDomaine= (Integer) domServ.save(domaine);
Assert.assertTrue(pkDomaine==DOMAINE_ID);
Domaine domFound=domServ.findDomaineById(DOMAINE_ID);
Assert.assertTrue(domFound.getId()==DOMAINE_ID
&& "ssn2crypte".equals(domFound.getSsn()));
}
Avec un peu de chance et une bonne configuration de log4j.xml (voir mon billet sur ce sujet), vous aurez les traces ci-dessous :
Hibernate:
insert
into
domaine
(description, libelle, ssn, id)
values
(?, ?, ?, ?)
TRACE- binding 'dommaine1 exemple' to parameter: 1 TRACE- binding 'dom1' to parameter: 2 TRACE- binding '1' to parameter: 4 Hibernate:
select
domaine0_.id as id0_0_,
domaine0_.description as descript2_0_0_,
domaine0_.libelle as libelle0_0_,
domaine0_.ssn as ssn0_0_
from
domaine domaine0_
where
domaine0_.id=?
TRACE- binding '1' to parameter: 1
....
Disons que tout n'a pas été expliqué dans ce billet car beaucoup de notions sont traitées ici.
J'espère néanmoins que c'est suffisamment clair.
Commentaires
Bonjour,
J'ai essayé de mettre en place votre solution, mais je rencontre l'erreur suivante :
Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/util/EqualsHelper
at org.jasypt.hibernate.type.AbstractEncryptedAsStringType.equals(AbstractEncryptedAsStringType.java:92)
...
Mes recherches ont été jusqu'à présent infructueuses. Auriez-vous une piste ?
Merci d'avance,
Julien Neuhart
Il suffit d'ajouter la dépendance hibernate-core-3xxxFinal.jar dans le classpath du projet
En effet, je dois être fatigué...
Dans tous les cas, ça fonctionne parfaitement maintenant.
Merci encore pour votre tutoriel !