2010-09-29 43 views
5

Mi clase de entidad User contiene el campo hash de contraseña, que es una matriz de bytes con una longitud fija (32 ya que es un hash SHA-256).Almacenamiento de un hash como matriz de bytes con JPA

@Entity 
public class User { 
    @Column(nullable=false) 
    private byte[] passwordHash; 
    ... 
} 

Como puede ver, no lo he anotado con nada especial, simplemente un NOT NULL.

Esto funciona, pero ¿funcionará? Mi esquema es generado por Hibernate, pero no sé exactamente qué genera (actualmente estoy usando una base de datos HSQL en memoria).

Me preocupa que, ya que no sabe que se trata de una matriz de longitud fija (el campo de la lengthColumn anotación se aplica únicamente a las cadenas), almacenará este hash en un campo BLOB que se añade en el registrar como un puntero (si entiendo correctamente cómo funcionan las bases de datos).

¿Es esto cierto y cómo puedo cambiar esto? ¿Debería codificar el hash como una cadena, con base64 o hex, aceptando el pequeño impacto de rendimiento/corrección de eso?

+0

¿Por qué no lo intentas con la base de datos real de destino y ves lo que genera? – skaffman

+0

@skaffman: He cambiado la base de datos a MySQL y genera una columna TINYBLOB –

+0

Lo que necesito es BINARY (32) –

Respuesta

1

tinyblob es una buena joice (mysql types reference), pero todas mis aplicaciones funcionan bien con Strings. Si realmente le interesan los milisegundos pruebe ambas versiones en un generador de perfiles y vea qué funciona mejor. Mi perfil preferido es el que está incluido en netbeans.

0

Por lo que yo sé, un hash SHA-256 es siempre sólo caracteres imprimibles (y si no, codificarlo base 64), por lo que la solución es que se puede almacenar como una cadena, a continuación, utilizar el campo length del Column anotación.

Luego tienes la longitud fija y no tienes dudas sobre el rendimiento.

+0

No, he visto el resultado y en realidad consiste principalmente en caracteres no imprimibles (o más bien no son datos de caracteres en absoluto). Por supuesto, podría base64 o hexadecimal codificarlo, pero si pudiera almacenarlo en forma binaria pura, sería bueno. –

5

Me preocupa que, ya que no sabe que se trata de una matriz de longitud fija (el campo de longitud de la columna de anotación se aplica únicamente a las cadenas), (...)

Si especifica la longitud de la columna, Hibernate utilizará esta información para determinar el tipo de columna SQL que se generará (TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB).

Lo que necesito es binario (32)

¿Usted intentó esto?

@Column(columnDefinition="BINARY(32) NOT NULL") 
private byte[] passwordHash; 
0

Puede que no sea tan eficiente, pero le sugiero que utilice String como el tipo de almacenamiento y traducir según sea necesario con los métodos get y set. Esto permite la máxima portabilidad para JPA entre diferentes bases de datos.

Utilizo una técnica similar con Fecha/Hora almacenando largos que representan tiempo desde época en UTC que me permite evitar problemas de zona horaria (la información de zona horaria no es portátil en las bases de datos en todas las bases de datos).

Cuestiones relacionadas