Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map a byte[] property with Hibernate?

I'm using Hibernate/Java to persist an entity to a database. The entity has a password field which is a String. When registring a user in my application, I hash the password using SHA-1 (I acknowledge this is a little weak). This produces a byte[] which I then convert to String using new String(byte[] arr); Whenever I want to log a user in, I simply retrieve the hashed password from the database (as String) and compare it with the digest of the input password at login using hashedPasswordFromDatabase.equals(SHA1_HASH(inputPassword));

This worked perfectly on my development system (Windows 7, JDK 1.6.0_23 / JDK 1.7, MySQL 5.5, Tomcat 6.0.26) but upon deploying it on our server (running JDK 1.6 on Linux), the equals method never evaluates to TRUE even for equal passwords. I quickly setup a new development system (Ubuntu 12.04, MySQL 5.5, JDK 1.7.0_03, Tomcat 7.0.22) and it doesn't work there too.

I'm aware of the possible encoding issues stated in the Java API documentation for the String class and also stated in several places here on SO. I've tried a couple of encodings suggested on this forum (e.g Base64, Latin-1) and I ended up with UnsupportedEncodingException. I think I'll be better off avoiding the String conversion. So how do I design my database such that the Hibernate-generated entity class comes up with byte[] for the password field instead of String?

like image 248
Sayo Oladeji Avatar asked May 14 '12 21:05

Sayo Oladeji


People also ask

How do you specify large objects in hibernate?

The @Lob annotation specifies that the database should store the property as Large Object. The columnDefinition in the @Column annotation defines the column type for the property. Since we're going to save byte array, we're using BLOB.

How do you convert a byte array into a string?

There are two ways to convert byte array to String: By using String class constructor. By using UTF-8 encoding.

What is @basic annotation in hibernate?

We can use the @Basic annotation to mark a basic type property: @Entity public class Course { @Basic @Id private int id; @Basic private String name; ... } In other words, the @Basic annotation on a field or a property signifies that it's a basic type and Hibernate should use the standard mapping for its persistence.

What is the use of @entity in hibernate?

@Entity annotation marks this class as an entity. @Table annotation specifies the table name where data of this entity is to be persisted. If you don't use @Table annotation, hibernate will use the class name as the table name by default. @Id annotation marks the identifier for this entity.


1 Answers

Yes, the problem is most likely in byte[] to String conversion. You must know that SHA produces raw byte array and there is no guarantee that arbitrary byte[] will produce valid String, irrespective to encoding. Thus your code was only working by accident.

Avoid the problem altogether by:

  • storing raw byte[] in BLOB - the safest and most storage-effective way. In Hibernate just use byte[] property on your POJO.

  • encode byte[] using base64 (check out Decode Base64 data in Java) and store it as a string.

BTW remember about salting!

like image 189
Tomasz Nurkiewicz Avatar answered Oct 09 '22 09:10

Tomasz Nurkiewicz